From a720e0ec2187e125c72517628993ba8d59dff87d Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 16 Jun 2020 12:28:56 -0500 Subject: [PATCH 001/239] Add fst280 files. --- lib/fst280/bpdecode280_101.f90 | 111 ++++++ lib/fst280/bpdecode280_74.f90 | 111 ++++++ lib/fst280/decode280_101.f90 | 154 ++++++++ lib/fst280/decode280_74.f90 | 153 ++++++++ lib/fst280/encode280_101.f90 | 46 +++ lib/fst280/encode280_74.f90 | 46 +++ lib/fst280/fst280.txt | 10 + lib/fst280/fst280d.f90 | 477 ++++++++++++++++++++++++ lib/fst280/fst280sim.f90 | 147 ++++++++ lib/fst280/ft4s280_params.f90 | 8 + lib/fst280/genfst280.f90 | 103 ++++++ lib/fst280/get_crc24.f90 | 25 ++ lib/fst280/get_fst280_bitmetrics.f90 | 118 ++++++ lib/fst280/ldpc_280_101_generator.f90 | 182 ++++++++++ lib/fst280/ldpc_280_101_parity.f90 | 476 ++++++++++++++++++++++++ lib/fst280/ldpc_280_74_generator.f90 | 209 +++++++++++ lib/fst280/ldpc_280_74_parity.f90 | 504 ++++++++++++++++++++++++++ lib/fst280/ldpcsim280_101.f90 | 139 +++++++ lib/fst280/ldpcsim280_74.f90 | 132 +++++++ lib/fst280/osd280_101.f90 | 403 ++++++++++++++++++++ lib/fst280/osd280_74.f90 | 403 ++++++++++++++++++++ 21 files changed, 3957 insertions(+) create mode 100644 lib/fst280/bpdecode280_101.f90 create mode 100644 lib/fst280/bpdecode280_74.f90 create mode 100644 lib/fst280/decode280_101.f90 create mode 100644 lib/fst280/decode280_74.f90 create mode 100644 lib/fst280/encode280_101.f90 create mode 100644 lib/fst280/encode280_74.f90 create mode 100644 lib/fst280/fst280.txt create mode 100644 lib/fst280/fst280d.f90 create mode 100644 lib/fst280/fst280sim.f90 create mode 100644 lib/fst280/ft4s280_params.f90 create mode 100644 lib/fst280/genfst280.f90 create mode 100644 lib/fst280/get_crc24.f90 create mode 100644 lib/fst280/get_fst280_bitmetrics.f90 create mode 100644 lib/fst280/ldpc_280_101_generator.f90 create mode 100644 lib/fst280/ldpc_280_101_parity.f90 create mode 100644 lib/fst280/ldpc_280_74_generator.f90 create mode 100644 lib/fst280/ldpc_280_74_parity.f90 create mode 100644 lib/fst280/ldpcsim280_101.f90 create mode 100644 lib/fst280/ldpcsim280_74.f90 create mode 100644 lib/fst280/osd280_101.f90 create mode 100644 lib/fst280/osd280_74.f90 diff --git a/lib/fst280/bpdecode280_101.f90 b/lib/fst280/bpdecode280_101.f90 new file mode 100644 index 000000000..a817a3d5c --- /dev/null +++ b/lib/fst280/bpdecode280_101.f90 @@ -0,0 +1,111 @@ +subroutine bpdecode280_101(llr,apmask,maxiterations,message101,cw,nharderror,iter,ncheck) +! +! A log-domain belief propagation decoder for the (280,101) code. +! + integer, parameter:: N=280, K=101, M=N-K + integer*1 cw(N),apmask(N) + integer*1 decoded(K) + integer*1 message101(101) + integer nrw(M),ncw + integer Nm(6,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(6,M) + real tanhtoc(6,M) + real zn(N) + real llr(N) + real Tmn + + include "ldpc_280_101_parity.f90" + + decoded=0 + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 +! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied' + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + decoded=cw(1:101) + call get_crc24(decoded,101,nbadcrc) + nharderror=count( (2*cw-1)*llr .lt. 0.0 ) + if(nbadcrc.eq.0) then + message101=decoded(1:101) + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + return + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo + nharderror=-1 + return +end subroutine bpdecode280_101 diff --git a/lib/fst280/bpdecode280_74.f90 b/lib/fst280/bpdecode280_74.f90 new file mode 100644 index 000000000..21b48d8db --- /dev/null +++ b/lib/fst280/bpdecode280_74.f90 @@ -0,0 +1,111 @@ +subroutine bpdecode280_74(llr,apmask,maxiterations,message74,cw,nharderror,iter,ncheck) +! +! A log-domain belief propagation decoder for the (280,74) code. +! + integer, parameter:: N=280, K=74, M=N-K + integer*1 cw(N),apmask(N) + integer*1 decoded(K) + integer*1 message74(74) + integer nrw(M),ncw + integer Nm(5,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(5,M) + real tanhtoc(5,M) + real zn(N) + real llr(N) + real Tmn + + include "ldpc_280_74_parity.f90" + + decoded=0 + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 +! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied' + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + decoded=cw(1:74) + call get_crc24(decoded,74,nbadcrc) + nharderror=count( (2*cw-1)*llr .lt. 0.0 ) + if(nbadcrc.eq.0) then + message74=decoded(1:74) + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + return + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:5,i)=tanh(-toc(1:5,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo + nharderror=-1 + return +end subroutine bpdecode280_74 diff --git a/lib/fst280/decode280_101.f90 b/lib/fst280/decode280_101.f90 new file mode 100644 index 000000000..838906c78 --- /dev/null +++ b/lib/fst280/decode280_101.f90 @@ -0,0 +1,154 @@ +subroutine decode280_101(llr,Keff,maxosd,norder,apmask,message101,cw,ntype,nharderror,dmin) +! +! A hybrid bp/osd decoder for the (280,101) code. +! +! maxosd<0: do bp only +! maxosd=0: do bp and then call osd once with channel llrs +! maxosd>1: do bp and then call osd maxosd times with saved bp outputs +! norder : osd decoding depth +! + integer, parameter:: N=280, K=101, M=N-K + integer*1 cw(N),apmask(N) + integer*1 nxor(N),hdec(N) + integer*1 message101(101),m101(101) + integer nrw(M),ncw + integer Nm(6,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(6,M) + real tanhtoc(6,M) + real zn(N),zsum(N),zsave(N,3) + real llr(N) + real Tmn + + include "ldpc_280_101_parity.f90" + + maxiterations=30 + nosd=0 + if(maxosd.gt.3) maxosd=3 + if(maxosd.eq.0) then ! osd with channel llrs + nosd=1 + zsave(:,1)=llr + elseif(maxosd.gt.0) then ! + nosd=maxosd + elseif(maxosd.lt.0) then ! just bp + nosd=0 + endif + + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + zsum=0.0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + zsum=zsum+zn + if(iter.gt.0 .and. iter.le.maxosd) then + zsave(:,iter)=zsum + endif + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + m101=0 + m101(1:101)=cw(1:101) + call get_crc24(m101,101,nbadcrc) + if(nbadcrc.eq.0) then + message101=cw(1:101) + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + nharderror=sum(nxor) + dmin=sum(nxor*abs(llr)) + ntype=1 + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + exit + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo ! bp iterations + + do i=1,nosd + zn=zsave(:,i) + call osd280_101(zn,Keff,apmask,norder,message101,cw,nharderror,dminosd) + if(nharderror.gt.0) then + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + dmin=sum(nxor*abs(llr)) + ntype=2 + return + endif + enddo + + ntype=0 + nharderror=-1 + dminosd=0.0 + + return +end subroutine decode280_101 diff --git a/lib/fst280/decode280_74.f90 b/lib/fst280/decode280_74.f90 new file mode 100644 index 000000000..0d0c6fc4f --- /dev/null +++ b/lib/fst280/decode280_74.f90 @@ -0,0 +1,153 @@ +subroutine decode280_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharderror,dmin) +! +! A hybrid bp/osd decoder for the (280,74) code. +! +! maxosd<0: do bp only +! maxosd=0: do bp and then call osd once with channel llrs +! maxosd>1: do bp and then call osd maxosd times with saved bp outputs +! norder : osd decoding depth +! + integer, parameter:: N=280, K=74, M=N-K + integer*1 cw(N),cwbest(N),apmask(N) + integer*1 nxor(N),hdec(N) + integer*1 message74(74),m74(74) + integer nrw(M),ncw + integer Nm(5,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(5,M) + real tanhtoc(5,M) + real zn(N),zsum(N),zsave(N,max(1,maxosd)) + real llr(N) + real Tmn + + include "ldpc_280_74_parity.f90" + + maxiterations=30 + nosd=0 + if(maxosd.eq.0) then ! osd with channel llrs + nosd=1 + zsave(:,1)=llr + elseif(maxosd.gt.0) then ! + nosd=maxosd + elseif(maxosd.lt.0) then ! just bp + nosd=0 + endif + + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + zsum=0.0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + zsum=zsum+zn + if(iter.gt.0 .and. iter.le.maxosd) then + zsave(:,iter)=zsum + endif + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + m74=0 + m74(1:74)=cw(1:74) + call get_crc24(m74,74,nbadcrc) + if(nbadcrc.eq.0) then + message74=cw(1:74) + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + nharderror=sum(nxor) + dmin=sum(nxor*abs(llr)) + ntype=1 + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + exit + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:5,i)=tanh(-toc(1:5,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo ! bp iterations + + do i=1,nosd + zn=zsave(:,i) + call osd280_74(zn,Keff,apmask,norder,message74,cw,nharderror,dminosd) + if(nharderror.ge.0) then + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + dmin=sum(nxor*abs(llr)) + ntype=2 + return + endif + enddo + + ntype=0 + nharderror=-1 + dminosd=0.0 + + return +end subroutine decode280_74 diff --git a/lib/fst280/encode280_101.f90 b/lib/fst280/encode280_101.f90 new file mode 100644 index 000000000..704816355 --- /dev/null +++ b/lib/fst280/encode280_101.f90 @@ -0,0 +1,46 @@ +subroutine encode280_101(message,codeword) + use, intrinsic :: iso_c_binding + use iso_c_binding, only: c_loc,c_size_t + use crc + + integer, parameter:: N=280, K=101, M=N-K + character*24 c24 + integer*1 codeword(N) + integer*1 gen(M,K) + integer*1 message(K) + integer*1 pchecks(M) + integer*4 ncrc24 + include "ldpc_280_101_generator.f90" + logical first + data first/.true./ + save first,gen + + if( first ) then ! fill the generator matrix + gen=0 + do i=1,M + do j=1,26 + read(g(i)(j:j),"(Z1)") istr + ibmax=4 + if(j.eq.26) ibmax=1 + do jj=1, ibmax + icol=(j-1)*4+jj + if( btest(istr,4-jj) ) gen(i,icol)=1 + enddo + enddo + enddo + first=.false. + endif + + do i=1,M + nsum=0 + do j=1,K + nsum=nsum+message(j)*gen(i,j) + enddo + pchecks(i)=mod(nsum,2) + enddo + + codeword(1:K)=message + codeword(K+1:N)=pchecks + + return +end subroutine encode280_101 diff --git a/lib/fst280/encode280_74.f90 b/lib/fst280/encode280_74.f90 new file mode 100644 index 000000000..e923d46f7 --- /dev/null +++ b/lib/fst280/encode280_74.f90 @@ -0,0 +1,46 @@ +subroutine encode280_74(message,codeword) + use, intrinsic :: iso_c_binding + use iso_c_binding, only: c_loc,c_size_t + use crc + + integer, parameter:: N=280, K=74, M=N-K + character*24 c24 + integer*1 codeword(N) + integer*1 gen(M,K) + integer*1 message(K) + integer*1 pchecks(M) + integer*4 ncrc24 + include "ldpc_280_74_generator.f90" + logical first + data first/.true./ + save first,gen + + if( first ) then ! fill the generator matrix + gen=0 + do i=1,M + do j=1,19 + read(g(i)(j:j),"(Z1)") istr + ibmax=4 + if(j.eq.19) ibmax=2 + do jj=1, ibmax + icol=(j-1)*4+jj + if( btest(istr,4-jj) ) gen(i,icol)=1 + enddo + enddo + enddo + first=.false. + endif + + do i=1,M + nsum=0 + do j=1,K + nsum=nsum+message(j)*gen(i,j) + enddo + pchecks(i)=mod(nsum,2) + enddo + + codeword(1:K)=message + codeword(K+1:N)=pchecks + + return +end subroutine encode280_74 diff --git a/lib/fst280/fst280.txt b/lib/fst280/fst280.txt new file mode 100644 index 000000000..5e2c1c935 --- /dev/null +++ b/lib/fst280/fst280.txt @@ -0,0 +1,10 @@ +------------------------------------------------------------------- + NSPS T/R TxT Tst Txtra Txtra-2.6s DF BW SNR77 SNR50 + (s) (s) (s) (s) (s) (Hz) (Hz) (dB) (dB) +------------------------------------------------------------------- + 800 15 10.93 0.5 3.57 0.97 15.00 60.0 -21.3 -23.2 + 1680 30 22.96 1.0 6.04 3.44 7.14 28.6 -24.5 -26.4 + 4000 60 54.67 1.0 4.33 1.73 3.00 12.0 -28.3 -30.2 + 8400 120 114.80 1.0 4.20 1.60 1.43 5.7 -31.5 -33.4 +21504 300 293.89 1.0 5.11 2.51 0.56 2.2 -35.5 -37.4 +------------------------------------------------------------------- diff --git a/lib/fst280/fst280d.f90 b/lib/fst280/fst280d.f90 new file mode 100644 index 000000000..edfee81f7 --- /dev/null +++ b/lib/fst280/fst280d.f90 @@ -0,0 +1,477 @@ +program fst280d + +! Decode fst280 data read from *.c2 or *.wav files. + + use packjt77 + include 'ft4s280_params.f90' + character arg*8,infile*80,fname*16,datetime*11 +! character ch1*1,ch4*4,cseq*31 +! character*22 decodes(100) + character*37 msg + character*120 data_dir + character*77 c77 + character*1 tr_designator + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real*8 fMHz + real llr(280),llra(280),llrb(280),llrc(280),llrd(280) + real candidates(100,3) + real bitmetrics(328,4) + integer ihdr(11) + integer*2, allocatable :: iwave(:) + integer*1 apmask(280),cw(280) + integer*1 hbits(328) + integer*1 message101(101),message74(74) + logical badsync,unpk77_success + + hmod=1.0 + Keff=91 + ndeep=3 + iwspr=0 + + nargs=iargc() + if(nargs.lt.1) then + print*,'Usage: fst280d [-a ] [-f fMHz] [-h hmod] [-k Keff] file1 [file2 ...]' + go to 999 + endif + iarg=1 + data_dir="." + call getarg(iarg,arg) + if(arg(1:2).eq.'-a') then + call getarg(iarg+1,data_dir) + iarg=iarg+2 + call getarg(iarg,arg) + endif + if(arg(1:2).eq.'-f') then + call getarg(iarg+1,arg) + read(arg,*) fMHz + iarg=iarg+2 + call getarg(iarg,arg) + endif + if(arg(1:2).eq.'-h') then + call getarg(iarg+1,arg) + read(arg,*) hmod + if(hmod.ne.1.and.hmod.ne.2.and.hmod.ne.4) then + print*,'invalid modulation index. h must be 1, 2, or 4' + goto 999 + endif + iarg=iarg+2 + call getarg(iarg,arg) + endif + if(arg(1:2).eq.'-k') then + call getarg(iarg+1,arg) + read(arg,*) Keff + if(Keff.le.74) iwspr=1 + iarg=iarg+2 + call getarg(iarg,arg) + endif + if(arg(1:2).eq.'-d') then + call getarg(iarg+1,arg) + read(arg,*) ndeep + iarg=iarg+2 + call getarg(iarg,arg) + endif + if(arg(1:2).eq.'-t') then + call getarg(iarg+1,arg) + read(arg,*) tr_designator + iarg=iarg+2 + endif + + nmax=15*12000 + select case (tr_designator) + case('A') + nsps=800 + nmax=15*12000 + ndown=32/hmod + case('B') + nsps=1680 + nmax=30*12000 + ndown=70/hmod + if(hmod.eq.4) ndown=15 + case('C') + nsps=4000 + nmax=60*12000 + ndown=160/hmod + case('D') + nsps=8400 + nmax=120*12000 + ndown=350/hmod + if(hmod.eq.4) ndown=84 + case('E') + nsps=21504 + nmax=300*12000 + ndown=896/hmod + end select + nss=nsps/ndown + fs=12000.0 !Sample rate + fs2=fs/ndown + nspsec=nint(fs2) + dt=1.0/fs !Sample interval (s) + dt2=1.0/fs2 + tt=nsps*dt !Duration of "itone" symbols (s) + + nfft1=2*int(nmax/2) + nh1=nfft1/2 + allocate( r_data(1:nfft1+2) ) + allocate( c_bigfft(0:nfft1/2) ) + + nfft2=nfft1/ndown + allocate( c2(0:nfft2-1) ) + allocate( cframe(0:164*nss-1) ) + allocate( iwave(nmax) ) + +!write(*,*) 'nsps: ',nsps +!write(*,*) 'nmax: ',nmax +!write(*,*) 'nss : ',nss +!write(*,*) 'nspsec: ',fs2 +!write(*,*) 'nfft1 : ',nfft1 +!write(*,*) 'nfft2 : ',nfft2 + + ngood=0 + ngoodsync=0 + nfile=0 + do ifile=iarg,nargs + nfile=nfile+1 + call getarg(ifile,infile) + open(10,file=infile,status='old',access='stream') + j1=index(infile,'.c2') + j2=index(infile,'.wav') + if(j1.gt.0) then + read(10,end=999) fname,ntrmin,fMHz,c2 + read(fname(8:11),*) nutc + write(datetime,'(i11)') nutc + else if(j2.gt.0) then + read(10,end=999) ihdr,iwave + read(infile(j2-4:j2-1),*) nutc + datetime=infile(j2-11:j2-1) + else + print*,'Wrong file format?' + go to 999 + endif + close(10) + + npts=nmax + fa=100.0 + fb=3500.0 + +! The big fft is done once and is used for calculating the smoothed spectrum +! and also for downconverting/downsampling each candidate. + r_data(1:nfft1)=iwave(1:nfft1) + r_data(nfft1+1:nfft1+2)=0.0 + call four2a(r_data,nfft1,1,-1,0) + c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + +! Get first approximation of candidate frequencies + call get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candidates) + + ndecodes=0 + isbest1=0 + isbest8=0 + fc21=fc0 + fc28=fc0 + do icand=1,ncand + fc0=candidates(icand,1) + xsnr=candidates(icand,2) + +! Downconvert and downsample a slice of the spectrum centered on the +! rough estimate of the candidates frequency. +! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. +! The size of the downsampled c2 array is nfft2=nfft1/ndown + + call fst280_downsample(c_bigfft,nfft1,ndown,fc0,c2) +! write(*,3001) c2(nfft2/3),candidates(icand,1:2) +!3001 format(2e15.6,2f10.3) + + do isync=0,1 + if(isync.eq.0) then + fc1=0.0 + is0=nint(fs2) + ishw=is0 + isst=4 + ifhw=10 + df=.1*8400/nsps + else if(isync.eq.1) then + fc1=fc28 + is0=isbest8 + ishw=4 + isst=1 + ifhw=10 + df=.02*8400/nsps + endif + + smax1=0.0 + smax8=0.0 + do if=-ifhw,ifhw + fc=fc1+df*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst280(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) + call sync_fst280(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) + if(sync8.gt.smax8) then + fc28=fc + isbest8=istart + smax8=sync8 + endif + if(sync1.gt.smax1) then + fc21=fc + isbest1=istart + smax1=sync1 + endif + enddo + enddo +! write(*,1022) ifile,icand,isync,fc1, & +! fc21,isbest1,smax1,fc28,isbest8,smax8 +!1022 format(i5,1x,i4,1x,i4,1x,f7.2,1x,2(1x,f7.2,1x,i5,1x,e9.3)) + enddo + + if(smax8/smax1 .lt. 0.65 ) then + fc2=fc21 + isbest=isbest1 + ntmax=4 + if(hmod .gt. 1.0) ntmax=1 + ntmin=1 + njitter=2 + else + fc2=fc28 + isbest=isbest8 + ntmax=4 + if(hmod .gt. 1.0) ntmax=1 + ntmin=1 + njitter=2 + endif + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + + call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) + + if(abs((isbest-fs2)/nss) .lt. 0.2 .and. abs(fc_synced-1500.0).lt.0.4) then + ngoodsync=ngoodsync+1 + endif + + do ijitter=0,2 + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=2 + if(ijitter.eq.2) ioffset=-2 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+164*nss-1) + s2=sum(cframe*conjg(cframe)) + cframe=cframe/sqrt(s2) + call get_fst280_bitmetrics(cframe,nss,hmod,bitmetrics,badsync) + + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) + ns2=count(hbits( 9: 16).eq.(/0,1,0,0,1,1,1,0/)) + ns3=count(hbits(157:164).eq.(/0,0,0,1,1,0,1,1/)) + ns4=count(hbits(165:172).eq.(/0,1,0,0,1,1,1,0/)) + ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) + ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 +! if(nsync_qual.lt. 20) cycle + + scalefac=2.83 + llra( 1:140)=bitmetrics( 17:156, 1) + llra(141:280)=bitmetrics(173:312, 1) + llra=scalefac*llra + llrb( 1:140)=bitmetrics( 17:156, 2) + llrb(141:280)=bitmetrics(173:312, 2) + llrb=scalefac*llrb + llrc( 1:140)=bitmetrics( 17:156, 3) + llrc(141:280)=bitmetrics(173:312, 3) + llrc=scalefac*llrc + llrd( 1:140)=bitmetrics( 17:156, 4) + llrd(141:280)=bitmetrics(173:312, 4) + llrd=scalefac*llrd + apmask=0 + + do itry=ntmax,ntmin,-1 + if(itry.eq.1) llr=llra + if(itry.eq.2) llr=llrb + if(itry.eq.3) llr=llrc + if(itry.eq.4) llr=llrd + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iwspr.eq.0) then + maxosd=2 + call decode280_101(llr,Keff,maxosd,ndeep,apmask,message101,cw,ntype,nharderrors,dmin) + else + maxosd=2 + call decode280_74(llr,Keff,maxosd,ndeep,apmask,message74,cw,ntype,nharderrors,dmin) + endif + if(nharderrors .ge.0) then + if(iwspr.eq.0) then + write(c77,'(77i1)') message101(1:77) + call unpack77(c77,0,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,0,msg,unpk77_success) + endif + if(nharderrors .ge.0 .and. unpk77_success) then + ngood=ngood+1 + write(*,1100) nfile,icand,xsnr,dt_synced,fc_synced, & + itry,ntype,nharderrors,dmin,ijitter,nsync_qual,msg(1:22) +1100 format(i5,i5,f6.1,f6.2,f7.1,i4,i4,i4,f7.2,i6,i6,2x,a22) + goto 2002 + else + cycle + endif + endif + enddo ! metrics + enddo ! istart jitter +2002 continue + enddo !candidate list + enddo !files + nfiles=nargs-iarg+1 + write(*,*) 'nfiles: ',nfiles,' ngood: ',ngood,' ngoodsync: ',ngoodsync + write(*,1120) +1120 format("") + +999 end program fst280d + +subroutine sync_fst280(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + +! Compute sync power for a complex, downsampled FST280 signal. + + include 'ft4s280_params.f90' + complex cd0(0:np-1) + complex, allocatable, save :: csync(:) + complex, allocatable, save :: csynct(:) + complex ctwk(8*nss) + complex z1,z2,z3 + logical first + integer isyncword(0:7) + real f0save + data isyncword/0,1,3,2,1,0,2,3/ + data first/.true./ + data f0save/0.0/ + save first,twopi,dt,fac,f0save + + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Statement function for power + + if( first ) then + allocate( csync(8*nss) ) + allocate( csynct(8*nss) ) + twopi=8.0*atan(1.0) + dt=1/fs + k=1 + phi=0.0 + do i=0,7 + dphi=twopi*hmod*(isyncword(i)-1.5)/real(nss) + do j=1,nss + csync(k)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + k=k+1 + enddo + enddo + first=.false. + fac=1.0/(8.0*nss) + endif + + if(f0.ne.f0save) then + dphi=twopi*f0*dt + phi=0.0 + do i=1,8*nss + ctwk(i)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + enddo + csynct=ctwk*csync + f0save=f0 + endif + + i1=i0 !Costas arrays + i2=i0+78*nss + i3=i0+156*nss + + s1=0.0 + s2=0.0 + s3=0.0 + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + enddo + + sync = s1+s2+s3 + + return +end subroutine sync_fst280 + +subroutine fst280_downsample(c_bigfft,nfft1,ndown,f0,c1) + +! Output: Complex data in c(), sampled at 12000/ndown Hz + + complex c_bigfft(0:nfft1/2) + complex c1(0:nfft1/ndown-1) + + df=12000.0/nfft1 + i0=nint(f0/df) + c1(0)=c_bigfft(i0) + nfft2=nfft1/ndown + do i=1,nfft2/2 + if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) + if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) + enddo + c1=c1/nfft2 + call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain + return + +end subroutine fst280_downsample + +subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candidates) + + complex c_bigfft(0:nfft1/2) + real candidates(100,3) + real s(18000) + real s2(18000) + data nfft1z/-1/ + save nfft1z + + nh1=nfft1/2 + df1=fs/nfft1 + baud=fs/nsps + df2=baud/2.0 + nd=df1/df2 + ndh=nd/2 + ia=fa/df2 + ib=fb/df2 + s=0. + do i=ia,ib + j0=nint(i*df2/df1) + do j=j0-ndh,j0+ndh + s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + enddo + enddo + call pctile(s(ia:ib),ib-ia+1,30,base) + s=s/base + nh=hmod + do i=ia,ib + s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) + s2(i)=db(s2(i)) - 48.5 + enddo + + if(nh.eq.1) thresh=-29.5 + if(nh.eq.2) thresh=-27.0 + if(nh.eq.4) thresh=-25.0 + + ncand=0 + do i=ia,ib + if((s2(i).gt.s2(i-1)).and. & + (s2(i).gt.s2(i+1)).and. & + (s2(i).gt.thresh).and.ncand.lt.100) then + ncand=ncand+1 + candidates(ncand,1)=df2*i + candidates(ncand,2)=s2(i) + endif + enddo + + return +end subroutine get_candidates_fst280 diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 new file mode 100644 index 000000000..72026344b --- /dev/null +++ b/lib/fst280/fst280sim.f90 @@ -0,0 +1,147 @@ +program fst280sim + +! Generate simulated signals for experimental slow FT4 mode + + use wavhdr + use packjt77 + include 'ft4s280_params.f90' !Set various constants + type(hdr) h !Header for .wav file + character arg*12,fname*17 + character msg37*37,msgsent37*37,c77*77 + character tr_designator*1 + complex, allocatable :: c0(:) + complex, allocatable :: c(:) + real, allocatable :: wave(:) + integer itone(NN) + integer*1 msgbits(101) + integer*2, allocatable :: iwave(:) !Generated full-length waveform + +! Get command-line argument(s) + nargs=iargc() + if(nargs.ne.9) then + print*,'Usage: fst280sim "message" type f0 DT h fdop del nfiles snr' + print*,'Examples: fst280sim "K1JT K9AN EN50" C 1500 0.0 1.0 0.1 1.0 10 -15' + print*,'A: 15 sec' + print*,'B: 30 sec' + print*,'C: 1 min' + print*,'D: 2 min' + print*,'E: 5 min' + go to 999 + endif + call getarg(1,msg37) !Message to be transmitted + call getarg(2,arg) + read(arg,*) tr_designator !TR selector + call getarg(3,arg) + read(arg,*) f0 !Frequency (only used for single-signal) + call getarg(4,arg) + read(arg,*) xdt !Time offset from nominal (s) + call getarg(5,arg) + read(arg,*) hmod !Modulation index, h + call getarg(6,arg) + read(arg,*) fspread !Watterson frequency spread (Hz) + call getarg(7,arg) + read(arg,*) delay !Watterson delay (ms) + call getarg(8,arg) + read(arg,*) nfiles !Number of files + call getarg(9,arg) + read(arg,*) snrdb !SNR_2500 + + nfiles=abs(nfiles) + twopi=8.0*atan(1.0) + fs=12000.0 !Sample rate (Hz) + dt=1.0/fs !Sample interval (s) + baud=1.0/tt !Keying rate (baud) + select case (tr_designator) + case('A') + nsps=800 + nmax=15*12000 + case('B') + nsps=1680 + nmax=30*12000 + case('C') + nsps=4000 + nmax=60*12000 + case('D') + nsps=8400 + nmax=120*12000 + case('E') + nsps=21504 + nmax=300*12000 + end select + nz=nsps*NN + nz2=nsps*NN2 + txt=nz2*dt !Transmission length (s) + tt=nsps*dt !Duration of symbols (s) + allocate( c0(0:nmax-1) ) + allocate( c(0:nmax-1) ) + allocate( wave(nmax) ) + allocate( iwave(nmax) ) + + bandwidth_ratio=2500.0/(fs/2.0) + sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) + if(snrdb.gt.90.0) sig=1.0 + + i3=-1 + n3=-1 + call pack77(msg37,i3,n3,c77) + call genfst280(msg37,0,msgsent37,msgbits,itone,iwspr) + + write(*,*) + write(*,'(a9,a37)') 'Message: ',msgsent37 + write(*,1000) f0,xdt,hmod,txt,snrdb +1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',f6.3,' TxT:',f6.1,' SNR:',f6.1) + write(*,*) + if(i3.eq.1) then + write(*,*) ' mycall hiscall hisgrid' + write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77) + else + write(*,'(a14)') 'Message bits: ' + write(*,'(50i1,1x,24i1)') msgbits + endif + write(*,*) + write(*,'(a17)') 'Channel symbols: ' + write(*,'(10i1)') itone + write(*,*) + +! call sgran() + + fsample=12000.0 + icmplx=1 + call gen_fst280wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) + k=nint((xdt+1.0)/dt)-nsps + c0=cshift(c0,-k) + if(k.gt.0) c0(0:k-1)=0.0 + if(k.lt.0) c0(nmax+k:nmax-1)=0.0 + + do ifile=1,nfiles + c=c0 + if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nmax,NZ,fs,delay,fspread) + c=sig*c + wave=real(c) + if(snrdb.lt.90) then + do i=1,nmax !Add gaussian noise at specified SNR + xnoise=gran() + wave(i)=wave(i) + xnoise + enddo + endif + gain=100.0 + if(snrdb.lt.90.0) then + wave=gain*wave + else + datpk=maxval(abs(wave)) + fac=32766.9/datpk + wave=fac*wave + endif + if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." + iwave=nint(wave) + h=default_header(12000,nmax) + write(fname,1102) ifile +1102 format('000000_',i6.6,'.wav') + open(10,file=fname,status='unknown',access='stream') + write(10) h,iwave !Save to *.wav file + close(10) + write(*,1110) ifile,xdt,f0,snrdb,fname +1110 format(i4,f7.2,f8.2,f7.1,2x,a17) + enddo + +999 end program fst280sim diff --git a/lib/fst280/ft4s280_params.f90 b/lib/fst280/ft4s280_params.f90 new file mode 100644 index 000000000..dc1519160 --- /dev/null +++ b/lib/fst280/ft4s280_params.f90 @@ -0,0 +1,8 @@ +! FT4S280 +! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols + +parameter (KK=77) !Information bits (77 + CRC24) +parameter (ND=140) !Data symbols +parameter (NS=24) !Sync symbols +parameter (NN=NS+ND) !Sync and data symbols (164) +parameter (NN2=NS+ND+2) !Total channel symbols (166) diff --git a/lib/fst280/genfst280.f90 b/lib/fst280/genfst280.f90 new file mode 100644 index 000000000..e074b5080 --- /dev/null +++ b/lib/fst280/genfst280.f90 @@ -0,0 +1,103 @@ +subroutine genfst280(msg0,ichk,msgsent,msgbits,i4tone,iwspr) + +! Input: +! - msg0 requested message to be transmitted +! - ichk if ichk=1, return only msgsent +! - msgsent message as it will be decoded +! - i4tone array of audio tone values, {0,1,2,3} +! - iwspr 0: (280,101)/crc24, 1: (280,74)/crc24 +! +! Frame structure: +! s8 d70 s8 d70 s8 + +! Message duration: TxT = 164*8400/12000 = 114.8 s + + use packjt77 + include 'ft4s280_params.f90' + character*37 msg0 + character*37 message !Message to be generated + character*37 msgsent !Message as it will be received + character*77 c77 + character*24 c24 + integer*4 i4tone(NN),itmp(ND) + integer*1 codeword(2*ND) + integer*1 msgbits(101),rvec(77) + integer isyncword(8) + integer ncrc24 + logical unpk77_success + data isyncword/0,1,3,2,1,0,2,3/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ + message=msg0 + + do i=1, 37 + if(ichar(message(i:i)).eq.0) then + message(i:37)=' ' + exit + endif + enddo + do i=1,37 !Strip leading blanks + if(message(1:1).ne.' ') exit + message=message(i+1:) + enddo + + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) + call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent + msgbits=0 + iwspr=0 + if(i3.eq.0.and.n3.eq.6) then + iwspr=1 + read(c77,'(50i1)') msgbits(1:50) + call get_crc24(msgbits,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(51:74) + else + read(c77,'(77i1)') msgbits(1:77) + call get_crc24(msgbits,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(78:101) + endif + + if(ichk.eq.1) go to 999 + if(unpk77_success) go to 2 +1 msgbits=0 + itone=0 + msgsent='*** bad message *** ' + go to 999 + + entry get_ft4s280_tones_from_bits(msgbits,i4tone,iwspr) + +2 continue + + if(iwspr.eq.0) then + call encode280_101(msgbits,codeword) + else + call encode280_74(msgbits(1:74),codeword) + endif + +! Grayscale mapping: +! bits tone +! 00 0 +! 01 1 +! 11 2 +! 10 3 + + do i=1,ND + is=codeword(2*i)+2*codeword(2*i-1) + if(is.le.1) itmp(i)=is + if(is.eq.2) itmp(i)=3 + if(is.eq.3) itmp(i)=2 + enddo + + i4tone(1:8)=isyncword + i4tone(9:78)=itmp(1:70) + i4tone(79:86)=isyncword + i4tone(87:156)=itmp(71:140) + i4tone(157:164)=isyncword + +999 return + +end subroutine genfst280 diff --git a/lib/fst280/get_crc24.f90 b/lib/fst280/get_crc24.f90 new file mode 100644 index 000000000..cb7f3a05f --- /dev/null +++ b/lib/fst280/get_crc24.f90 @@ -0,0 +1,25 @@ +subroutine get_crc24(mc,len,ncrc) +! +! 1. To calculate 24-bit CRC, mc(1:len-24) is the message and mc(len-23:len) are zero. +! 2. To check a received CRC, mc(1:len) is the received message plus CRC. +! ncrc will be zero if the received message/CRC are consistent. +! + character c24*24 + integer*1 mc(len) + integer*1 r(25),p(25) + integer ncrc +! polynomial for 24-bit CRC 0x100065b + data p/1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1,1,0,1,1/ + +! divide by polynomial + r=mc(1:25) + do i=0,len-25 + r(25)=mc(i+25) + r=mod(r+r(1)*p,2) + r=cshift(r,1) + enddo + + write(c24,'(24b1)') r(1:24) + read(c24,'(b24.24)') ncrc + +end subroutine get_crc24 diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 new file mode 100644 index 000000000..a50088f66 --- /dev/null +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -0,0 +1,118 @@ +subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) + + include 'ft4s280_params.f90' + complex cd(0:NN*nss-1) + complex cs(0:3,NN) + complex csymb(nss) + complex, allocatable, save :: c1(:,:) ! ideal waveforms, 20 samples per symbol, 4 tones + complex cp(0:3) ! accumulated phase shift over symbol types 0:3 + complex csum,cterm + integer icos8(0:7) + integer graymap(0:3) + integer ip(1) + logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits + logical first + logical badsync + real bitmetrics(2*NN,4) + real s2(0:65535) + real s4(0:3,NN) + data icos8/0,1,3,2,1,0,2,3/ + data graymap/0,1,3,2/ + data first/.true./ + save first,one,cp + + if(first) then + allocate(c1(nss,0:3)) + one=.false. + do i=0,65535 + do j=0,15 + if(iand(i,2**j).ne.0) one(i,j)=.true. + enddo + enddo + twopi=8.0*atan(1.0) + dphi=twopi*hmod/nss + do itone=0,3 + dp=(itone-1.5)*dphi + phi=0.0 + do j=1,nss + c1(j,itone)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dp,twopi) + enddo + cp(itone)=cmplx(cos(phi),sin(phi)) + enddo + first=.false. + endif + + do k=1,NN + i1=(k-1)*NSS + csymb=cd(i1:i1+NSS-1) + do itone=0,3 + cs(itone,k)=sum(csymb*conjg(c1(:,itone))) + enddo + s4(0:3,k)=abs(cs(0:3,k)) + enddo + +! Sync quality check + is1=0 + is2=0 + is3=0 + badsync=.false. + ibmax=0 + + do k=1,8 + ip=maxloc(s4(:,k)) + if(icos8(k-1).eq.(ip(1)-1)) is1=is1+1 + ip=maxloc(s4(:,k+78)) + if(icos8(k-1).eq.(ip(1)-1)) is2=is2+1 + ip=maxloc(s4(:,k+156)) + if(icos8(k-1).eq.(ip(1)-1)) is3=is3+1 + enddo + nsync=is1+is2+is3 !Number of correct hard sync symbols, 0-24 + + badsync=.false. +! if(nsync .lt. 8) then +! badsync=.true. +! return +! endif + + bitmetrics=0.0 + do nseq=1,4 !Try coherent sequences of 1, 2, and 4 symbols + if(nseq.eq.1) nsym=1 + if(nseq.eq.2) nsym=2 + if(nseq.eq.3) nsym=4 + if(nseq.eq.4) nsym=8 + nt=4**nsym + do ks=1,NN-nsym+1,nsym + s2=0 + do i=0,nt-1 + csum=0 + cterm=1 + do j=0,nsym-1 + ntone=mod(i/4**(nsym-1-j),4) + csum=csum+cs(graymap(ntone),ks+j)*cterm + cterm=cterm*conjg(cp(graymap(ntone))) + enddo + s2(i)=abs(csum) + enddo + ipt=1+(ks-1)*2 + if(nsym.eq.1) ibmax=1 + if(nsym.eq.2) ibmax=3 + if(nsym.eq.4) ibmax=7 + if(nsym.eq.8) ibmax=15 + do ib=0,ibmax + bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & + maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) + if(ipt+ib.gt.2*NN) cycle + bitmetrics(ipt+ib,nseq)=bm + enddo + enddo + enddo + bitmetrics(321:328,4)=bitmetrics(321:328,3) + + call normalizebmet(bitmetrics(:,1),2*NN) + call normalizebmet(bitmetrics(:,2),2*NN) + call normalizebmet(bitmetrics(:,3),2*NN) + call normalizebmet(bitmetrics(:,4),2*NN) + return + +end subroutine get_fst280_bitmetrics diff --git a/lib/fst280/ldpc_280_101_generator.f90 b/lib/fst280/ldpc_280_101_generator.f90 new file mode 100644 index 000000000..521e80026 --- /dev/null +++ b/lib/fst280/ldpc_280_101_generator.f90 @@ -0,0 +1,182 @@ +character*26 g(179) + +data g/ & + "c919bcbfe4091279702a761e98", & + "51b952dddd36200cf73cc1ed30", & + "15871d32e8e888439180cf6fd8", & + "581f858f6c89ee5ccb91664358", & + "3515e85cedf905eda366a8fc20", & + "e9fcaa6aaa9bab21bc91174e80", & + "0ac73221d424e8747628b13968", & + "4999f7116446f1a7a7a1453a30", & + "0e92773bff2a6d4f09caa48898", & + "7dfaec97c17679f6c3b6a425f0", & + "00707d76a2a7d90297ee39f660", & + "8048cc93fc4ad84ccfc021e6e0", & + "0c13df64062fed419c9bf43400", & + "5523d84459c826b7bc3335d508", & + "828ee2552144d041ed44ada8e0", & + "3f1b89fbd93f674df4813f0898", & + "4e13df64062fed419c9bf43400", & + "5d8645307d3d442991d6efafd0", & + "e5cd9b98d73aab17ce04c4df10", & + "06d26e11e2d02e9cb4f191c2b0", & + "5630cebc5b3a09f7d4fe58fab0", & + "bbfa9591589229738ecbc19288", & + "c98654d1f1f16d507e9bb77cf0", & + "c2af2107bb2bdff49d909dc730", & + "51da7da0c9b1bd18a15f580068", & + "5bdfd83e7ca3097146a5359428", & + "34fc4d397d97ca3ceb272f49a0", & + "6716a6d027ade94010e9aa90b0", & + "62ac7bb089d1a13f6e89f92348", & + "737c3ab63210e195e92e8ad478", & + "db2da5b8a21d22a7122ad80e60", & + "1226525dba4221d4768a495878", & + "a99deb4c9b7d316917b1ece958", & + "8123fb46556f22a0b57bdc7eb0", & + "cc6a80e87a7a9bf8addb17a6a8", & + "3d42bb6ca1c8d30e6cee77aa10", & + "ad15a0c2f36d4409a458cc83c0", & + "766a04039736bd8be23513ae58", & + "257a3da77558d7c707170c30c8", & + "8e54a55fd9f00eb669ab787678", & + "4ef1a73cc9da8670d83bebc588", & + "be8bb82558d44fea1ab27376a0", & + "ea9db4f88c60edf410cb0128d8", & + "a84e19a5261818262ee7247278", & + "51f99e4ea17cf84038d4e00bd0", & + "610560db4095fc44d2465308a0", & + "7688745b59c3d6baa6950c4f50", & + "4b8794914d365b6802bd62a9c8", & + "f62c211d05ed28802b9d278298", & + "b9cd45b2ffa8c0dd688f8d2bc0", & + "68555e81f4227a48e76878bc98", & + "7ab58f11d41a2d38b80d2a7558", & + "aba2d33e69077b6acad393af68", & + "81e5f58fa3ab563e73706201a8", & + "7586aea816750c41671eaa7db8", & + "af37b0a97ba5334a3dd01948e8", & + "4fdc03c263a0c42dcc265f7dc8", & + "b23f2d7f28748944cdfffd5af0", & + "5c1e6f37dfba8feacaafdb0f78", & + "3a85b051f4f1c930d921f60828", & + "72319352bd8022ce2cae2e7858", & + "78b79f633ac6879e3ac3a005a0", & + "9f0c470609669953b23328de60", & + "86d3745d50142c82a066ab9490", & + "743e7bf411490f36a9799e37e8", & + "9b8378677870933ef360d7e418", & + "5f7adbf515b663a1434b0d47d8", & + "13249a96b14c6cdcfae5009eb0", & + "da9570e0a52125d0dc4dec4430", & + "ada13ce2dbcb57e2f5b31172f0", & + "84f5485886d4157e9d37efb4d0", & + "23f58c3200bab4ae5dee54edd0", & + "d4377aadf8acb19d4369613ac8", & + "17cefcf65c87885fb6c4d537a0", & + "59d70b8536488298930aaea7f8", & + "49e8dbb08c2ecdaa84bb6a5378", & + "e1694479ecc1f87e503f959e50", & + "dbb3fc94f0f70d4bd4dcf302d8", & + "4ccb3a56f80c236424683b1588", & + "f4f123c72596a00397d56fcdf8", & + "13f9cf266a6957b87cd2b576f0", & + "0904d341bc0878460cd8361ac0", & + "69fd534caf2cccf9c90659a038", & + "757d3d95089a5bc20a7b77c618", & + "30df1d7b8124415c73190b08d8", & + "d39319584987dce0c44176d5d8", & + "1a81df299eb7434a5b6b9322a0", & + "fe4acfab1c22c7bea222f1a6b0", & + "2f2fde37fa8f87a318f7bcda10", & + "fae712210c23665aa7a3f10620", & + "977b8407c7fd22d7715077ee78", & + "2ab2b355b3477df0b738c49d48", & + "93a2468cfd11a522b310069d88", & + "0e5ae6e789ded3c0d436359318", & + "9ece0b13a3c06d560a15d3c448", & + "838e8bbf5e671503ea72ba3118", & + "7c827de9a87d740763c69c6778", & + "1fe395e4e2e6d1373602243488", & + "f2c4efee3d0ce2e22749be9e20", & + "46405cca0e40f36ab83de4a998", & + "8b6e931355a79630ef2dbdbdb8", & + "10df1d3b8124415c72190b08d8", & + "cdff258b07a4f7cfe5c2210ba8", & + "1515e85cedf904eda366a8fc20", & + "a38276f2d077abc1da5e177868", & + "67a7b5ab66f21f391d306c3330", & + "29492cc630f9bad1fdedf0c990", & + "490a6dd38170eab178f7cebf78", & + "ca9db4e88c60edf410cf0128d8", & + "e3f1c23fa8531fb1e4c7768d88", & + "39d7d8fbbb689b2a9bedfd4dd0", & + "d1b952dd5d36200cf734c1ed30", & + "0820a5ccb970d1ab109d84d700", & + "58bc3c509fcd7874e9b1533ba8", & + "08ed7724ac66b7974499b12f40", & + "4738529b2fd04afd89184b64b8", & + "7155b496e3b9f687135b4c55b8", & + "b5d1d3cf38b1765dd730d8b960", & + "296de2c373773a869b9cf804c8", & + "1cdf18b99bcc47ae72bf59df68", & + "ad0888db89dd794be0b2660e98", & + "1f2a8db9db19cd4d69a735d930", & + "44b720007480382206fdbfbb18", & + "c63817aad3801fb993ea9032c0", & + "d44707db5a0b489fd48748cca8", & + "49f98a67c6e128a5300f7ccc50", & + "04849fa9da91d4514355406388", & + "dfad3a11788cf6f6517f987de8", & + "47078a19e38a0763cabd7c8d70", & + "aafa7f864f0da5bc78f8e57ba8", & + "8acb5a34e18e111023b3e7b1f8", & + "5acc41263d6aa1767e5e6acdc8", & + "27623a9f6c1174e35394191820", & + "1f2bde9c006b3b687964b1c5e0", & + "b01c6e357bce202244b4a88d08", & + "61c85d74d7e97576507c9b0e88", & + "bcad5a44d75ae40bc43559d268", & + "10584eaf319552194418563de0", & + "b29b011d717d10a22de0983980", & + "2f9b42d7d2299449491c612b20", & + "389ba33f5fec3bfb3a0ef86b50", & + "3df89f78c19fb27ae7ff19d360", & + "65ff6ba4e107aa919a6afb4ff0", & + "39b607c3f09679a62e134cd390", & + "94ad06f7b7414727d92f998930", & + "169200459898ae0bc7f06714a0", & + "c7a5a945adebb554cb4d86a830", & + "f37c3ab63230e195e92e8ad478", & + "559a51262e91aa9ba0fa96af48", & + "fb2998ca916a557463d00fb160", & + "aa32462ada57a76ae132fc8de8", & + "e6df6b19f58bfee0b96b731b90", & + "e984335d40a54fe914a6249110", & + "ea73d8f3f14bd9fe2374e39120", & + "3adab8e51c36f53584e3669c88", & + "74ef69f64dc4fef86c3b1fe640", & + "d01c6bc112d7ae3e4ba4820a78", & + "62923979fd3c3d1153bcaaf338", & + "038f72995b5072df8fe5f4dfa0", & + "9f07e7cea2f1476fb035978790", & + "2a5aad6a75d5c86cab38fd0070", & + "a254a09cc3180854688d2aa9c8", & + "0495639712a04820f7038ae7c0", & + "d99fc716ca825ad45cca8f4518", & + "01b8d558073c0377ce67344a50", & + "2fbd0f86a17c3f93713fbd09a0", & + "c29dc84bec7b4cd00dd1c17380", & + "5e6238b823f530ae017a03f0e0", & + "51203d329c68b061977d78d4c0", & + "1186729e08cf1dfbec30237968", & + "40363018b431224a1f559d2908", & + "e334e78442b614a0c9a377e1b8", & + "ff2eda86339f589f96382f52e0", & + "58a30e07fc7a37a4f858623778", & + "f5067fe407a4c3b94ce7b63e48", & + "1d09ced788a3642bc0ec640ec8", & + "17734ca67d53cd9d8595970668", & + "47953c2105bd94bff079672740", & + "3444682d1dc0ab486036c1b0d0"/ diff --git a/lib/fst280/ldpc_280_101_parity.f90 b/lib/fst280/ldpc_280_101_parity.f90 new file mode 100644 index 000000000..b1cabb7d1 --- /dev/null +++ b/lib/fst280/ldpc_280_101_parity.f90 @@ -0,0 +1,476 @@ +data Mn/ & + 150, 151, 161, & + 6, 164, 172, & + 92, 128, 158, & + 2, 63, 135, & + 3, 14, 22, & + 4, 18, 29, & + 5, 17, 164, & + 7, 99, 179, & + 8, 88, 115, & + 9, 62, 110, & + 10, 107, 154, & + 11, 50, 140, & + 12, 28, 33, & + 13, 31, 170, & + 15, 69, 175, & + 16, 77, 178, & + 19, 70, 91, & + 20, 95, 177, & + 21, 96, 106, & + 23, 129, 168, & + 24, 49, 169, & + 25, 65, 102, & + 26, 82, 171, & + 27, 45, 137, & + 30, 89, 119, & + 32, 148, 158, & + 34, 94, 152, & + 35, 44, 92, & + 36, 39, 138, & + 37, 55, 58, & + 38, 121, 165, & + 40, 81, 162, & + 41, 139, 150, & + 42, 43, 83, & + 46, 80, 114, & + 47, 52, 54, & + 48, 166, 173, & + 38, 53, 87, & + 56, 64, 126, & + 57, 67, 127, & + 59, 156, 159, & + 60, 97, 133, & + 61, 118, 161, & + 66, 100, 123, & + 68, 124, 131, & + 71, 101, 155, & + 72, 74, 144, & + 73, 112, 141, & + 75, 136, 149, & + 59, 78, 117, & + 79, 130, 163, & + 84, 93, 113, & + 86, 108, 163, & + 103, 146, 157, & + 70, 104, 145, & + 105, 128, 142, & + 74, 109, 122, & + 54, 111, 153, & + 116, 154, 176, & + 120, 132, 167, & + 21, 125, 147, & + 134, 143, 166, & + 7, 81, 160, & + 32, 99, 174, & + 1, 93, 104, & + 2, 69, 98, & + 3, 33, 152, & + 4, 46, 159, & + 5, 126, 178, & + 6, 127, 147, & + 8, 101, 110, & + 9, 73, 158, & + 10, 120, 123, & + 11, 122, 125, & + 12, 58, 170, & + 13, 88, 105, & + 14, 133, 150, & + 15, 92, 100, & + 16, 90, 108, & + 17, 44, 106, & + 18, 35, 175, & + 19, 94, 179, & + 20, 97, 153, & + 22, 109, 130, & + 23, 63, 140, & + 24, 37, 146, & + 25, 141, 168, & + 26, 95, 115, & + 27, 107, 149, & + 28, 91, 168, & + 29, 134, 144, & + 30, 31, 169, & + 34, 40, 96, & + 36, 156, 172, & + 39, 61, 135, & + 41, 42, 121, & + 43, 57, 117, & + 45, 62, 72, & + 47, 137, 167, & + 48, 83, 116, & + 49, 65, 173, & + 1, 50, 141, & + 2, 8, 150, & + 3, 62, 140, & + 4, 104, 124, & + 5, 128, 139, & + 6, 64, 159, & + 7, 103, 176, & + 2, 11, 104, & + 9, 71, 85, & + 10, 80, 131, & + 11, 17, 130, & + 12, 148, 156, & + 13, 39, 164, & + 14, 15, 167, & + 14, 32, 89, & + 16, 114, 135, & + 8, 164, 169, & + 18, 107, 129, & + 19, 53, 102, & + 20, 134, 170, & + 21, 43, 145, & + 22, 24, 76, & + 23, 44, 146, & + 19, 22, 101, & + 25, 41, 48, & + 26, 46, 58, & + 27, 82, 87, & + 28, 78, 179, & + 29, 73, 81, & + 30, 116, 161, & + 31, 96, 157, & + 15, 58, 172, & + 10, 33, 160, & + 34, 110, 118, & + 33, 35, 113, & + 36, 166, 175, & + 32, 37, 152, & + 38, 57, 74, & + 13, 82, 176, & + 40, 42, 45, & + 25, 57, 177, & + 40, 120, 136, & + 21, 92, 121, & + 23, 34, 147, & + 12, 45, 54, & + 3, 46, 48, & + 47, 91, 169, & + 26, 61, 132, & + 49, 123, 147, & + 1, 79, 88, & + 51, 97, 101, & + 52, 155, 177, & + 24, 72, 105, & + 54, 84, 106, & + 55, 63, 126, & + 56, 72, 163, & + 38, 63, 170, & + 37, 71, 178, & + 20, 49, 59, & + 30, 60, 117, & + 61, 65, 137, & + 41, 98, 119, & + 47, 51, 62, & + 6, 76, 131, & + 55, 70, 81, & + 66, 111, 119, & + 60, 67, 94, & + 68, 112, 132, & + 9, 69, 157, & + 70, 75, 89, & + 69, 108, 153, & + 44, 53, 77, & + 29, 130, 149, & + 65, 103, 125, & + 74, 85, 156, & + 56, 67, 68, & + 77, 138, 144, & + 28, 95, 138, & + 79, 133, 142, & + 35, 50, 86, & + 73, 78, 137, & + 27, 126, 175, & + 83, 100, 143, & + 42, 142, 168, & + 40, 48, 158, & + 86, 95, 174, & + 39, 109, 129, & + 59, 88, 125, & + 6, 89, 155, & + 36, 90, 102, & + 75, 97, 141, & + 43, 146, 148, & + 93, 149, 168, & + 52, 83, 94, & + 80, 87, 106, & + 91, 96, 143, & + 3, 43, 126, & + 98, 154, 162, & + 99, 115, 173, & + 5, 84, 100, & + 64, 133, 154, & + 90, 117, 158, & + 7, 108, 151, & + 4, 128, 167, & + 105, 127, 136, & + 1, 83, 114, & + 107, 127, 134, & + 4, 108, 170, & + 92, 109, 171, & + 110, 113, 122, & + 111, 124, 166, & + 12, 112, 150, & + 2, 95, 105, & + 17, 114, 118, & + 99, 139, 144, & + 116, 165, 178, & + 5, 22, 73, & + 16, 115, 162, & + 13, 34, 41, & + 120, 122, 151, & + 121, 160, 172, & + 8, 37, 102, & + 123, 140, 165, & + 7, 53, 93, & + 9, 10, 130, & + 11, 30, 58, & + 31, 66, 179, & + 14, 31, 45, & + 15, 88, 129, & + 18, 101, 148, & + 16, 62, 127, & + 17, 20, 68, & + 19, 86, 98, & + 25, 106, 163, & + 135, 152, 163, & + 23, 124, 137, & + 21, 28, 71, & + 24, 26, 153, & + 29, 90, 123, & + 32, 113, 134, & + 35, 57, 169, & + 27, 50, 139, & + 33, 60, 65, & + 38, 61, 142, & + 145, 153, 154, & + 39, 67, 81, & + 36, 84, 133, & + 18, 161, 173, & + 93, 155, 171, & + 42, 99, 131, & + 49, 87, 162, & + 51, 56, 168, & + 47, 125, 144, & + 44, 143, 159, & + 46, 75, 138, & + 52, 78, 107, & + 54, 109, 174, & + 64, 110, 179, & + 159, 165, 174, & + 66, 135, 171, & + 63, 76, 117, & + 59, 111, 120, & + 72, 160, 166, & + 70, 118, 156, & + 55, 157, 173, & + 74, 100, 176, & + 77, 112, 145, & + 69, 141, 147, & + 94, 140, 151, & + 51, 82, 104, & + 85, 98, 167, & + 80, 119, 146, & + 97, 122, 172, & + 90, 96, 132, & + 79, 91, 178, & + 103, 136, 152, & + 1, 76, 85, & + 115, 121, 149, & + 116, 175, 177/ + +data Nm/ & + 65, 102, 151, 207, 278, 0, & + 4, 66, 103, 109, 214, 0, & + 5, 67, 104, 147, 198, 0, & + 6, 68, 105, 205, 209, 0, & + 7, 69, 106, 201, 218, 0, & + 2, 70, 107, 165, 190, 0, & + 8, 63, 108, 204, 225, 0, & + 9, 71, 103, 118, 223, 0, & + 10, 72, 110, 170, 226, 0, & + 11, 73, 111, 134, 226, 0, & + 12, 74, 109, 112, 227, 0, & + 13, 75, 113, 146, 213, 0, & + 14, 76, 114, 140, 220, 0, & + 5, 77, 115, 116, 229, 0, & + 15, 78, 115, 133, 230, 0, & + 16, 79, 117, 219, 232, 0, & + 7, 80, 112, 215, 233, 0, & + 6, 81, 119, 231, 249, 0, & + 17, 82, 120, 125, 234, 0, & + 18, 83, 121, 160, 233, 0, & + 19, 61, 122, 144, 238, 0, & + 5, 84, 123, 125, 218, 0, & + 20, 85, 124, 145, 237, 0, & + 21, 86, 123, 154, 239, 0, & + 22, 87, 126, 142, 235, 0, & + 23, 88, 127, 149, 239, 0, & + 24, 89, 128, 183, 243, 0, & + 13, 90, 129, 179, 238, 0, & + 6, 91, 130, 174, 240, 0, & + 25, 92, 131, 161, 227, 0, & + 14, 92, 132, 228, 229, 0, & + 26, 64, 116, 138, 241, 0, & + 13, 67, 134, 136, 244, 0, & + 27, 93, 135, 145, 220, 0, & + 28, 81, 136, 181, 242, 0, & + 29, 94, 137, 191, 248, 0, & + 30, 86, 138, 159, 223, 0, & + 31, 38, 139, 158, 245, 0, & + 29, 95, 114, 188, 247, 0, & + 32, 93, 141, 143, 186, 0, & + 33, 96, 126, 163, 220, 0, & + 34, 96, 141, 185, 251, 0, & + 34, 97, 122, 193, 198, 0, & + 28, 80, 124, 173, 255, 0, & + 24, 98, 141, 146, 229, 0, & + 35, 68, 127, 147, 256, 0, & + 36, 99, 148, 164, 254, 0, & + 37, 100, 126, 147, 186, 0, & + 21, 101, 150, 160, 252, 0, & + 12, 102, 181, 243, 0, 0, & + 152, 164, 253, 271, 0, 0, & + 36, 153, 195, 257, 0, 0, & + 38, 120, 173, 225, 0, 0, & + 36, 58, 146, 155, 258, 0, & + 30, 156, 166, 266, 0, 0, & + 39, 157, 177, 253, 0, 0, & + 40, 97, 139, 142, 242, 0, & + 30, 75, 127, 133, 227, 0, & + 41, 50, 160, 189, 263, 0, & + 42, 161, 168, 244, 0, 0, & + 43, 95, 149, 162, 245, 0, & + 10, 98, 104, 164, 232, 0, & + 4, 85, 156, 158, 262, 0, & + 39, 107, 202, 259, 0, 0, & + 22, 101, 162, 175, 244, 0, & + 44, 167, 228, 261, 0, 0, & + 40, 168, 177, 247, 0, 0, & + 45, 169, 177, 233, 0, 0, & + 15, 66, 170, 172, 269, 0, & + 17, 55, 166, 171, 265, 0, & + 46, 110, 159, 238, 0, 0, & + 47, 98, 154, 157, 264, 0, & + 48, 72, 130, 182, 218, 0, & + 47, 57, 139, 176, 267, 0, & + 49, 171, 192, 256, 0, 0, & + 123, 165, 262, 278, 0, 0, & + 16, 173, 178, 268, 0, 0, & + 50, 129, 182, 257, 0, 0, & + 51, 151, 180, 276, 0, 0, & + 35, 111, 196, 273, 0, 0, & + 32, 63, 130, 166, 247, 0, & + 23, 128, 140, 271, 0, 0, & + 34, 100, 184, 195, 207, 0, & + 52, 155, 201, 248, 0, 0, & + 110, 176, 272, 278, 0, 0, & + 53, 181, 187, 234, 0, 0, & + 38, 128, 196, 252, 0, 0, & + 9, 76, 151, 189, 230, 0, & + 25, 116, 171, 190, 0, 0, & + 79, 191, 203, 240, 275, 0, & + 17, 90, 148, 197, 276, 0, & + 3, 28, 78, 144, 210, 0, & + 52, 65, 194, 225, 250, 0, & + 27, 82, 168, 195, 270, 0, & + 18, 88, 179, 187, 214, 0, & + 19, 93, 132, 197, 275, 0, & + 42, 83, 152, 192, 274, 0, & + 66, 163, 199, 234, 272, 0, & + 8, 64, 200, 216, 251, 0, & + 44, 78, 184, 201, 267, 0, & + 46, 71, 125, 152, 231, 0, & + 22, 120, 191, 223, 0, 0, & + 54, 108, 175, 277, 0, 0, & + 55, 65, 105, 109, 271, 0, & + 56, 76, 154, 206, 214, 0, & + 19, 80, 155, 196, 235, 0, & + 11, 89, 119, 208, 257, 0, & + 53, 79, 172, 204, 209, 0, & + 57, 84, 188, 210, 258, 0, & + 10, 71, 135, 211, 259, 0, & + 58, 167, 212, 263, 0, 0, & + 48, 169, 213, 268, 0, 0, & + 52, 136, 211, 241, 0, 0, & + 35, 117, 207, 215, 0, 0, & + 9, 88, 200, 219, 279, 0, & + 59, 100, 131, 217, 280, 0, & + 50, 97, 161, 203, 262, 0, & + 43, 135, 215, 265, 0, 0, & + 25, 163, 167, 273, 0, 0, & + 60, 73, 143, 221, 263, 0, & + 31, 96, 144, 222, 279, 0, & + 57, 74, 211, 221, 274, 0, & + 44, 73, 150, 224, 240, 0, & + 45, 105, 212, 237, 0, 0, & + 61, 74, 175, 189, 254, 0, & + 39, 69, 156, 183, 198, 0, & + 40, 70, 206, 208, 232, 0, & + 3, 56, 106, 205, 0, 0, & + 20, 119, 188, 230, 0, 0, & + 51, 84, 112, 174, 226, 0, & + 45, 111, 165, 251, 0, 0, & + 60, 149, 169, 275, 0, 0, & + 42, 77, 180, 202, 248, 0, & + 62, 91, 121, 208, 241, 0, & + 4, 95, 117, 236, 261, 0, & + 49, 143, 206, 277, 0, 0, & + 24, 99, 162, 182, 237, 0, & + 29, 178, 179, 256, 0, 0, & + 33, 106, 216, 243, 0, 0, & + 12, 85, 104, 224, 270, 0, & + 48, 87, 102, 192, 269, 0, & + 56, 180, 185, 245, 0, 0, & + 62, 184, 197, 255, 0, 0, & + 47, 91, 178, 216, 254, 0, & + 55, 122, 246, 268, 0, 0, & + 54, 86, 124, 193, 273, 0, & + 61, 70, 145, 150, 269, 0, & + 26, 113, 193, 231, 0, 0, & + 49, 89, 174, 194, 279, 0, & + 1, 33, 77, 103, 213, 0, & + 1, 204, 221, 270, 0, 0, & + 27, 67, 138, 236, 277, 0, & + 58, 83, 172, 239, 246, 0, & + 11, 59, 199, 202, 246, 0, & + 46, 153, 190, 250, 0, 0, & + 41, 94, 113, 176, 265, 0, & + 54, 132, 170, 266, 0, 0, & + 3, 26, 72, 186, 203, 0, & + 41, 68, 107, 255, 260, 0, & + 63, 134, 222, 264, 0, 0, & + 1, 43, 131, 249, 0, 0, & + 32, 199, 219, 252, 0, 0, & + 51, 53, 157, 235, 236, 0, & + 2, 7, 114, 118, 0, 0, & + 31, 217, 224, 260, 0, 0, & + 37, 62, 137, 212, 264, 0, & + 60, 99, 115, 205, 272, 0, & + 20, 87, 90, 185, 194, 253, & + 21, 92, 118, 148, 242, 0, & + 14, 75, 121, 158, 209, 0, & + 23, 210, 250, 261, 0, 0, & + 2, 94, 133, 222, 274, 0, & + 37, 101, 200, 249, 266, 0, & + 64, 187, 258, 260, 0, 0, & + 15, 81, 137, 183, 280, 0, & + 59, 108, 140, 267, 0, 0, & + 18, 142, 153, 280, 0, 0, & + 16, 69, 159, 217, 276, 0, & + 8, 82, 129, 228, 259, 0/ + +data nrw/ & +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, & +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, & +5,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,5,5,5,4, & +5,5,5,4,5,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4, & +5,4,5,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5, & +5,4,4,5,5,5,5,5,5,5,4,4,4,4,5,5,5,4,4,5, & +5,5,5,4,5,5,5,4,4,5,4,4,5,5,5,4,5,4,4,5, & +5,4,4,5,4,5,5,4,5,5,4,5,5,5,4,5,4,5,5,4, & +4,4,5,4,4,5,5,6,5,5,4,5,5,4,5,4,4,5,5/ + +ncw=3 + diff --git a/lib/fst280/ldpc_280_74_generator.f90 b/lib/fst280/ldpc_280_74_generator.f90 new file mode 100644 index 000000000..8625e2fd2 --- /dev/null +++ b/lib/fst280/ldpc_280_74_generator.f90 @@ -0,0 +1,209 @@ +character*19 g(206) + +data g/ & + "f7842fd3230388e2388", & + "2ebea0b08a75d2261cc", & + "b037d38c9d9b9a5e520", & + "936729d89fd5474ecdc", & + "539287b4ef7ee4534a8", & + "a4d283607d3a5020508", & + "f4539f434b8b8585444", & + "1c7b56480cc52fa5228", & + "a1c788b066ac91de648", & + "6592203e5579bbd9248", & + "aaa9e1247a75c451654", & + "f06cbce3477735fcdac", & + "0b3bd1b2eb21c4a58e8", & + "9789c1e9afeaefe132c", & + "6f3090a344262fe9588", & + "523326e51ec096314c0", & + "33ad630efa2f0547a1c", & + "128e4669c5290997554", & + "d21ba68abe8a45c7388", & + "14792ff07616833ddcc", & + "f336703cec81b57b9d4", & + "dcb179c1ede8a193578", & + "19a5027744d4d5fc3ec", & + "416cb1bc4f9fc83f03c", & + "245f12d8a19902ff678", & + "3a9653df6b08f65e934", & + "94870f042c4015d30d0", & + "7db806a2e50336e78bc", & + "d799458b3559526d2a8", & + "77e7cfd440146912610", & + "67c9ca176f188a99b1c", & + "dd736cb5cbfaa6f6cb0", & + "1210f8c1310dde522e4", & + "3bdf62af1d111a616a8", & + "556e0b2cb64629c03e0", & + "153b771b34fd0e24038", & + "677111e1bd26700abec", & + "ba6a2362c2249224dc8", & + "96d96eda9f7d897b3a4", & + "ee632974db8208ed678", & + "ba6e8ace7ca7e5dba2c", & + "112aa2048b8723c3794", & + "04125e68eed114d3a74", & + "6ce3283112a3d15df18", & + "6717fa02c4245ac3cd4", & + "bba51cf56c4ab60d0e8", & + "bf02614f56d95557004", & + "db8d9537a66dae71170", & + "2aa9e1247a75c451614", & + "37887845236cdc5a498", & + "5a0fd4682a5116e3bd4", & + "66a13f0f4838812f4b0", & + "0189837a15fb8a3ea28", & + "bd833c6eb639530bb4c", & + "ad2cb697dcd08717134", & + "d28c4e5b0e4f93921e8", & + "4a10da97be29877762c", & + "11b1d2dbd7e029e0034", & + "8cebf77857fd5b4b2d0", & + "8cf76e6929f04a6f2d0", & + "4dfdef39d983b6ff054", & + "e19594dcc430c3f36f8", & + "b4e0a5979e86ca9e7d8", & + "c6e5822a81c720e1da8", & + "d8b1374afa4f4534c2c", & + "d50ebca7ce5022d72b8", & + "d1af50dba58c8b978d4", & + "0114771daca21b8a4e8", & + "5a12be303c2bcc6cad0", & + "75ba0d26c70194e20dc", & + "feeb4567ccdd6d44334", & + "de993868f8b317cdb08", & + "8c0f2fc7b031a0354ec", & + "df2ddab6d334a1316fc", & + "d410f54de1453f63024", & + "14870f042c4011d30d0", & + "bf8bb7654c089ff49f4", & + "48fe5211864e84af104", & + "a212348c05d3f2f7c8c", & + "1cb6e7158001aa32fa0", & + "bb2700d89c358ea9f74", & + "f5ff926daf5e6003708", & + "7eecbcdc28e9800b97c", & + "b38c9a3ff4e36761180", & + "aff8af260682347a39c", & + "24c2e6bf10c093cb8b8", & + "7633edd7825917114ec", & + "3383b1074eee8343950", & + "3d0636cf743b45409bc", & + "e6191c1e4753a438054", & + "a5ed8c6a5c54aaa2d0c", & + "2335c47d4da16e79fd4", & + "56f62a484a6243fea04", & + "090c7572a6b53ed67d8", & + "a12212511d2fe5a7a04", & + "55653c6f1cd716dfafc", & + "25fb9166056f5276e50", & + "b5500cd4a5a4903b794", & + "5aaa65c6ee1732ffa20", & + "702a7660612fd7307fc", & + "bbf00390ef7bb4219f4", & + "36a23bd84e7d142dc28", & + "00dd156a637e5b6cf34", & + "d960448d1d09f7a3d5c", & + "7cc7c47ef82e670f740", & + "0c72af8643fa31e0df8", & + "c60997484551c3304ec", & + "5234c7b54ce0fb97cd4", & + "e4551cf6ddc5bf7b85c", & + "7320bbe8f600cb3f654", & + "b25ac980a31e7d449e8", & + "da25337deba0f2a1024", & + "4b54fafbcdf9f159c70", & + "75252e36d57dc65a0c8", & + "9f792800ecd943f8784", & + "fb7d1b209de7997cd40", & + "f47e660b960bf39cda4", & + "630017e41ef1e01b3bc", & + "047d83c03cd1e69929c", & + "0b8be375675a21f6c50", & + "aebfa0b08a75d2261cc", & + "dcd8bfe5b2b83f3276c", & + "862503814b89c46f268", & + "caf108899bef63422e0", & + "0651e9975e9eb3049bc", & + "d2418a98d6be4bb1368", & + "0f886c109cbf0643a64", & + "ae76a8d1d71335942cc", & + "66a0d75d3f90f0d0c04", & + "51d30039a555c4ac8cc", & + "9d7a4b82e9323439734", & + "2475d34a372b289eba4", & + "2468b9122171f215a80", & + "f1eb642be43a6d15e74", & + "001d6a58165ada8f124", & + "dd770baa38e1f8c2fd8", & + "03e026dcb395529dc0c", & + "46dc96eb5146f71a614", & + "1402ba94f9d9e1ff3dc", & + "dd7970ccb883bf18678", & + "29ddaca7cd0bf0151f4", & + "865c5ec3ab28496ade4", & + "97d388a7557a659e7f8", & + "78ba47aec4ff81965dc", & + "26a0c75d3f90f0d0c04", & + "48bc3be9b33ad3a2960", & + "e9c4c425a39b4fa6520", & + "2a8cfed864a4c6f5bb8", & + "de273ccb39330dd42a0", & + "c7e0c4a6641be9a6934", & + "f8b8514aebccc0086a4", & + "0f2b8fda05f0d07629c", & + "8734be755b106490e04", & + "789a87c164b552602d4", & + "b588408fb1a6c128874", & + "9dddcc7da27769ac544", & + "288b20a6f933bab6328", & + "f38c9a3ff4e26761180", & + "dc5613392113fea3498", & + "62dcbccf74e9673662c", & + "729e135a6b13b1eb084", & + "3045e9bb3c808018868", & + "0d1e2b1a48642a04dac", & + "abb1dced614797b1288", & + "d29fba8d71829beb4a0", & + "8f4a38515de6db613c4", & + "67194fd309de34d2178", & + "fc73d1f5ea8fd6bf49c", & + "c6289740e2b97b8d29c", & + "6100d464faa8f4f3068", & + "2cb7e414a3da6ca0988", & + "b439b0fdfdf891f28ec", & + "b7d3aaa693c7f068120", & + "25d691a2bc6288c1c50", & + "52f1f88c882d24a5f9c", & + "9892d88821ebd874f1c", & + "fbda9cdf96a2c4e9b30", & + "7716ec58ca1ac237f90", & + "6993c923557c6c68b68", & + "eb32c8c6a30622d0c28", & + "ba7980eafa803e1d3dc", & + "a92b5a9ca961bf9a5bc", & + "36ecfc5928f2c7be4cc", & + "ab854e4b7a9944840d4", & + "62db1428386b97101e4", & + "734bc6eb48e3024c7a0", & + "5b06c92d9089c7e6e38", & + "c7d02e44052506c6d14", & + "d35f553090ce90d3b04", & + "5462cf72405e2525d7c", & + "c9b85ab24e5188e5d18", & + "d0bb27c6092eb01dc7c", & + "37036df9c68bfe4eb24", & + "4387156e9b00d277ce0", & + "a39bb776102878c96a4", & + "d6f1cd9b329e7d0b374", & + "d74ba376dbaa9de5270", & + "58df754b03e0fa7a714", & + "14dfaffe9ab7ba93ce8", & + "36652b8b0226f6cc940", & + "777234e72dd631499ac", & + "581964c38824c5a58f8", & + "187cba427974172c6a0", & + "a90588951da0399e6f0", & + "3ddb7427533342f51cc", & + "25d308610cf492a5ac4"/ diff --git a/lib/fst280/ldpc_280_74_parity.f90 b/lib/fst280/ldpc_280_74_parity.f90 new file mode 100644 index 000000000..302edeb25 --- /dev/null +++ b/lib/fst280/ldpc_280_74_parity.f90 @@ -0,0 +1,504 @@ +data Mn/ & + 95, 150, 172, & + 154, 178, 184, & + 1, 90, 164, & + 2, 143, 199, & + 3, 33, 70, & + 4, 23, 86, & + 5, 127, 174, & + 6, 18, 110, & + 7, 59, 99, & + 8, 94, 124, & + 9, 168, 206, & + 10, 165, 175, & + 11, 64, 166, & + 12, 103, 156, & + 13, 46, 80, & + 14, 35, 172, & + 15, 20, 189, & + 16, 162, 188, & + 17, 74, 200, & + 19, 52, 178, & + 21, 87, 182, & + 22, 30, 144, & + 24, 37, 126, & + 25, 107, 171, & + 26, 114, 187, & + 27, 36, 53, & + 28, 91, 169, & + 29, 100, 109, & + 31, 71, 192, & + 32, 106, 190, & + 34, 160, 204, & + 38, 93, 136, & + 39, 77, 196, & + 40, 43, 177, & + 41, 56, 66, & + 42, 115, 151, & + 44, 155, 180, & + 45, 105, 128, & + 47, 54, 203, & + 48, 117, 120, & + 49, 62, 183, & + 50, 185, 202, & + 51, 83, 147, & + 55, 75, 170, & + 57, 79, 205, & + 58, 67, 159, & + 60, 81, 201, & + 61, 89, 184, & + 63, 119, 198, & + 65, 104, 152, & + 68, 149, 191, & + 69, 134, 167, & + 72, 102, 129, & + 73, 95, 108, & + 76, 82, 146, & + 78, 112, 173, & + 84, 141, 161, & + 85, 138, 157, & + 92, 132, 145, & + 96, 131, 181, & + 97, 110, 121, & + 98, 133, 153, & + 74, 101, 195, & + 111, 118, 183, & + 113, 130, 163, & + 116, 176, 193, & + 125, 188, 194, & + 135, 142, 148, & + 28, 137, 140, & + 33, 68, 150, & + 46, 51, 179, & + 6, 186, 198, & + 79, 138, 197, & + 1, 30, 122, & + 1, 58, 162, & + 2, 9, 172, & + 3, 71, 161, & + 4, 119, 142, & + 5, 147, 160, & + 6, 73, 183, & + 7, 118, 202, & + 8, 82, 98, & + 2, 47, 56, & + 10, 92, 151, & + 11, 19, 150, & + 12, 169, 179, & + 13, 43, 188, & + 14, 15, 192, & + 14, 82, 120, & + 16, 131, 155, & + 17, 123, 148, & + 18, 60, 117, & + 11, 90, 134, & + 20, 154, 195, & + 21, 47, 166, & + 22, 24, 86, & + 23, 48, 167, & + 21, 22, 190, & + 25, 44, 53, & + 26, 50, 64, & + 4, 27, 95, & + 28, 87, 205, & + 1, 29, 183, & + 30, 132, 185, & + 31, 108, 180, & + 32, 38, 174, & + 33, 36, 128, & + 34, 125, 134, & + 35, 190, 201, & + 30, 33, 142, & + 37, 61, 81, & + 32, 65, 70, & + 39, 40, 41, & + 36, 39, 78, & + 40, 140, 144, & + 42, 100, 194, & + 9, 13, 111, & + 20, 25, 115, & + 45, 140, 165, & + 10, 46, 60, & + 15, 43, 200, & + 23, 113, 158, & + 16, 49, 150, & + 12, 26, 164, & + 51, 88, 115, & + 52, 63, 141, & + 44, 101, 187, & + 34, 54, 173, & + 55, 93, 139, & + 56, 67, 102, & + 57, 62, 152, & + 29, 80, 89, & + 5, 59, 195, & + 18, 100, 156, & + 28, 61, 162, & + 31, 62, 163, & + 38, 52, 103, & + 50, 149, 175, & + 65, 122, 138, & + 66, 112, 171, & + 24, 68, 198, & + 68, 69, 84, & + 51, 69, 108, & + 70, 146, 159, & + 3, 91, 201, & + 72, 143, 149, & + 6, 129, 188, & + 74, 104, 153, & + 54, 75, 186, & + 76, 95, 200, & + 77, 120, 168, & + 41, 104, 182, & + 79, 144, 187, & + 58, 171, 193, & + 37, 85, 135, & + 8, 174, 197, & + 83, 163, 176, & + 53, 67, 184, & + 85, 99, 196, & + 76, 84, 138, & + 77, 87, 194, & + 86, 123, 202, & + 57, 89, 146, & + 27, 90, 97, & + 91, 126, 136, & + 46, 107, 113, & + 55, 189, 204, & + 94, 111, 130, & + 19, 139, 152, & + 96, 121, 158, & + 75, 88, 94, & + 93, 98, 157, & + 79, 81, 203, & + 42, 148, 206, & + 101, 156, 181, & + 97, 114, 154, & + 103, 170, 175, & + 78, 106, 191, & + 105, 109, 135, & + 64, 74, 176, & + 73, 92, 169, & + 80, 132, 181, & + 71, 105, 186, & + 110, 137, 204, & + 21, 159, 192, & + 35, 66, 137, & + 48, 127, 205, & + 114, 182, 193, & + 2, 18, 163, & + 59, 116, 129, & + 99, 107, 119, & + 7, 121, 125, & + 102, 109, 141, & + 19, 87, 160, & + 96, 165, 172, & + 63, 118, 147, & + 17, 143, 196, & + 124, 164, 173, & + 112, 117, 131, & + 52, 151, 180, & + 127, 198, 199, & + 106, 110, 167, & + 116, 177, 178, & + 72, 130, 155, & + 49, 177, 203, & + 128, 133, 166, & + 133, 189, 206, & + 75, 145, 191, & + 1, 51, 133, & + 83, 136, 168, & + 4, 155, 179, & + 3, 127, 157, & + 90, 170, 190, & + 5, 140, 164, & + 6, 139, 196, & + 31, 34, 142, & + 7, 53, 104, & + 11, 39, 109, & + 145, 178, 197, & + 25, 143, 146, & + 8, 134, 181, & + 9, 61, 174, & + 10, 41, 198, & + 12, 135, 159, & + 14, 79, 113, & + 13, 33, 66, & + 153, 161, 188, & + 16, 20, 136, & + 17, 45, 180, & + 22, 100, 116, & + 15, 118, 191, & + 157, 179, 184, & + 37, 110, 185, & + 30, 141, 168, & + 27, 176, 189, & + 28, 76, 186, & + 24, 26, 111, & + 124, 185, 199, & + 45, 122, 126, & + 35, 72, 147, & + 32, 119, 194, & + 36, 50, 138, & + 23, 29, 175, & + 42, 67, 124, & + 40, 89, 94, & + 43, 103, 199, & + 49, 151, 167, & + 44, 84, 204, & + 47, 48, 122, & + 46, 105, 195, & + 55, 96, 177, & + 57, 59, 106, & + 38, 54, 193, & + 58, 86, 152, & + 63, 101, 162, & + 60, 98, 123, & + 64, 115, 205, & + 62, 200, 201, & + 65, 73, 154, & + 56, 82, 183, & + 69, 91, 99, & + 70, 202, 203, & + 74, 112, 197, & + 71, 131, 206, & + 77, 165, 171, & + 68, 97, 120, & + 78, 156, 161, & + 80, 114, 148, & + 83, 92, 187, & + 88, 102, 158, & + 107, 145, 166, & + 122, 125, 130, & + 85, 117, 170, & + 121, 128, 169, & + 126, 129, 173, & + 153, 158, 160, & + 93, 144, 149, & + 88, 123, 137, & + 81, 108, 182, & + 132, 139, 192/ + +data Nm/ & + 3, 74, 75, 103, 209, & + 4, 76, 83, 189, 0, & + 5, 77, 145, 212, 0, & + 6, 78, 101, 211, 0, & + 7, 79, 133, 214, 0, & + 8, 72, 80, 147, 215, & + 9, 81, 192, 217, 0, & + 10, 82, 156, 221, 0, & + 11, 76, 117, 222, 0, & + 12, 84, 120, 223, 0, & + 13, 85, 93, 218, 0, & + 14, 86, 124, 224, 0, & + 15, 87, 117, 226, 0, & + 16, 88, 89, 225, 0, & + 17, 88, 121, 231, 0, & + 18, 90, 123, 228, 0, & + 19, 91, 197, 229, 0, & + 8, 92, 134, 189, 0, & + 20, 85, 169, 194, 0, & + 17, 94, 118, 228, 0, & + 21, 95, 98, 185, 0, & + 22, 96, 98, 230, 0, & + 6, 97, 122, 243, 0, & + 23, 96, 141, 237, 0, & + 24, 99, 118, 220, 0, & + 25, 100, 124, 237, 0, & + 26, 101, 164, 235, 0, & + 27, 69, 102, 135, 236, & + 28, 103, 132, 243, 0, & + 22, 74, 104, 110, 234, & + 29, 105, 136, 216, 0, & + 30, 106, 112, 241, 0, & + 5, 70, 107, 110, 226, & + 31, 108, 128, 216, 0, & + 16, 109, 186, 240, 0, & + 26, 107, 114, 242, 0, & + 23, 111, 155, 233, 0, & + 32, 106, 137, 253, 0, & + 33, 113, 114, 218, 0, & + 34, 113, 115, 245, 0, & + 35, 113, 152, 223, 0, & + 36, 116, 174, 244, 0, & + 34, 87, 121, 246, 0, & + 37, 99, 127, 248, 0, & + 38, 119, 229, 239, 0, & + 15, 71, 120, 166, 250, & + 39, 83, 95, 249, 0, & + 40, 97, 187, 249, 0, & + 41, 123, 205, 247, 0, & + 42, 100, 138, 242, 0, & + 43, 71, 125, 143, 209, & + 20, 126, 137, 200, 0, & + 26, 99, 158, 217, 0, & + 39, 128, 149, 253, 0, & + 44, 129, 167, 251, 0, & + 35, 83, 130, 260, 0, & + 45, 131, 163, 252, 0, & + 46, 75, 154, 254, 0, & + 9, 133, 190, 252, 0, & + 47, 92, 120, 256, 0, & + 48, 111, 135, 222, 0, & + 41, 131, 136, 258, 0, & + 49, 126, 196, 255, 0, & + 13, 100, 180, 257, 0, & + 50, 112, 139, 259, 0, & + 35, 140, 186, 226, 0, & + 46, 130, 158, 244, 0, & + 51, 70, 141, 142, 266, & + 52, 142, 143, 261, 0, & + 5, 112, 144, 262, 0, & + 29, 77, 183, 264, 0, & + 53, 146, 204, 240, 0, & + 54, 80, 181, 259, 0, & + 19, 63, 148, 180, 263, & + 44, 149, 171, 208, 0, & + 55, 150, 160, 236, 0, & + 33, 151, 161, 265, 0, & + 56, 114, 178, 267, 0, & + 45, 73, 153, 173, 225, & + 15, 132, 182, 268, 0, & + 47, 111, 173, 279, 0, & + 55, 82, 89, 260, 0, & + 43, 157, 210, 269, 0, & + 57, 142, 160, 248, 0, & + 58, 155, 159, 273, 0, & + 6, 96, 162, 254, 0, & + 21, 102, 161, 194, 0, & + 125, 171, 270, 278, 0, & + 48, 132, 163, 245, 0, & + 3, 93, 164, 213, 0, & + 27, 145, 165, 261, 0, & + 59, 84, 181, 269, 0, & + 32, 129, 172, 277, 0, & + 10, 168, 171, 245, 0, & + 1, 54, 101, 150, 0, & + 60, 170, 195, 251, 0, & + 61, 164, 176, 266, 0, & + 62, 82, 172, 256, 0, & + 9, 159, 191, 261, 0, & + 28, 116, 134, 230, 0, & + 63, 127, 175, 255, 0, & + 53, 130, 193, 270, 0, & + 14, 137, 177, 246, 0, & + 50, 148, 152, 217, 0, & + 38, 179, 183, 250, 0, & + 30, 178, 202, 252, 0, & + 24, 166, 191, 271, 0, & + 54, 105, 143, 279, 0, & + 28, 179, 193, 218, 0, & + 8, 61, 184, 202, 233, & + 64, 117, 168, 237, 0, & + 56, 140, 199, 263, 0, & + 65, 122, 166, 225, 0, & + 25, 176, 188, 268, 0, & + 36, 118, 125, 257, 0, & + 66, 190, 203, 230, 0, & + 40, 92, 199, 273, 0, & + 64, 81, 196, 231, 0, & + 49, 78, 191, 241, 0, & + 40, 89, 151, 266, 0, & + 61, 170, 192, 274, 0, & + 74, 139, 239, 249, 272, & + 91, 162, 256, 278, 0, & + 10, 198, 238, 244, 0, & + 67, 108, 192, 272, 0, & + 23, 165, 239, 275, 0, & + 7, 187, 201, 212, 0, & + 38, 107, 206, 274, 0, & + 53, 147, 190, 275, 0, & + 65, 168, 204, 272, 0, & + 60, 90, 199, 264, 0, & + 59, 104, 182, 280, 0, & + 62, 206, 207, 209, 0, & + 52, 93, 108, 221, 0, & + 68, 155, 179, 224, 0, & + 32, 165, 210, 228, 0, & + 69, 184, 186, 278, 0, & + 58, 73, 139, 160, 242, & + 129, 169, 215, 280, 0, & + 69, 115, 119, 214, 0, & + 57, 126, 193, 234, 0, & + 68, 78, 110, 216, 0, & + 4, 146, 197, 220, 0, & + 22, 115, 153, 277, 0, & + 59, 208, 219, 271, 0, & + 55, 144, 163, 220, 0, & + 43, 79, 196, 240, 0, & + 68, 91, 174, 268, 0, & + 51, 138, 146, 277, 0, & + 1, 70, 85, 123, 0, & + 36, 84, 200, 247, 0, & + 50, 131, 169, 254, 0, & + 62, 148, 227, 276, 0, & + 2, 94, 176, 259, 0, & + 37, 90, 204, 211, 0, & + 14, 134, 175, 267, 0, & + 58, 172, 212, 232, 0, & + 122, 170, 270, 276, 0, & + 46, 144, 185, 224, 0, & + 31, 79, 194, 276, 0, & + 57, 77, 227, 267, 0, & + 18, 75, 135, 255, 0, & + 65, 136, 157, 189, 0, & + 3, 124, 198, 214, 0, & + 12, 119, 195, 265, 0, & + 13, 95, 206, 271, 0, & + 52, 97, 202, 247, 0, & + 11, 151, 210, 234, 0, & + 27, 86, 181, 274, 0, & + 44, 177, 213, 273, 0, & + 24, 140, 154, 265, 0, & + 1, 16, 76, 195, 0, & + 56, 128, 198, 275, 0, & + 7, 106, 156, 222, 0, & + 12, 138, 177, 243, 0, & + 66, 157, 180, 235, 0, & + 34, 203, 205, 251, 0, & + 2, 20, 203, 219, 0, & + 71, 86, 211, 232, 0, & + 37, 105, 200, 229, 0, & + 60, 175, 182, 221, 0, & + 21, 152, 188, 279, 0, & + 41, 64, 80, 103, 260, & + 2, 48, 158, 232, 0, & + 42, 104, 233, 238, 0, & + 72, 149, 183, 236, 0, & + 25, 127, 153, 269, 0, & + 18, 67, 87, 147, 227, & + 17, 167, 207, 235, 0, & + 30, 98, 109, 213, 0, & + 51, 178, 208, 231, 0, & + 29, 88, 185, 280, 0, & + 66, 154, 188, 253, 0, & + 67, 116, 161, 241, 0, & + 63, 94, 133, 250, 0, & + 33, 159, 197, 215, 0, & + 73, 156, 219, 263, 0, & + 49, 72, 141, 201, 223, & + 4, 201, 238, 246, 0, & + 19, 121, 150, 258, 0, & + 47, 109, 145, 258, 0, & + 42, 81, 162, 262, 0, & + 39, 173, 205, 262, 0, & + 31, 167, 184, 248, 0, & + 45, 102, 187, 257, 0, & + 11, 174, 207, 264, 0/ + +data nrw/ & +5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & +4,4,4,4,4,4,4,5,4,5,4,4,5,4,4,4,4,4,4,4, & +4,4,4,4,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4, & +4,4,4,4,4,4,4,5,4,4,4,4,4,5,4,4,4,4,5,4, & +4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & +4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4, & +4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4, & +4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & +4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & +4,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,4,4, & +4,4,4,4,4,4/ + +ncw=3 diff --git a/lib/fst280/ldpcsim280_101.f90 b/lib/fst280/ldpcsim280_101.f90 new file mode 100644 index 000000000..df5e1f019 --- /dev/null +++ b/lib/fst280/ldpcsim280_101.f90 @@ -0,0 +1,139 @@ +program ldpcsim280_101 + +! End-to-end test of the (280,101)/crc24 encoder and decoders. + + use packjt77 + + parameter(N=280, K=101, M=N-K) + character*8 arg + character*37 msg0,msg + character*77 c77 + character*24 c24 + integer*1 msgbits(101) + integer*1 apmask(280) + integer*1 cw(280) + integer*1 codeword(N),message101(101) + integer ncrc24 + real rxdata(N),llr(N) + real llrd(280) + logical first,unpk77_success + data first/.true./ + + nargs=iargc() + if(nargs.ne.6 .and. nargs.ne.7) then + print*,'Usage : ldpcsim niter norder maxosd #trials s K [msg]' + print*,'e.g. ldpcsim280_101 20 3 2 1000 0.85 91 "K9AN K1JT FN20"' + print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' + print*,'niter : is the number of BP iterations.' + print*,'norder: -1 is BP only, norder>=0 is OSD order' + print*,'K :is the number of message+CRC bits and must be in the range [77,101]' + print*,'WSPR-format message is optional' + return + endif + call getarg(1,arg) + read(arg,*) max_iterations + call getarg(2,arg) + read(arg,*) norder + call getarg(3,arg) + read(arg,*) maxosd + call getarg(4,arg) + read(arg,*) ntrials + call getarg(5,arg) + read(arg,*) s + call getarg(6,arg) + read(arg,*) Keff + msg0='K9AN K1JT FN20 ' + if(nargs.eq.7) call getarg(7,msg0) + call pack77(msg0,i3,n3,c77) + call unpack77(c77,0,msg,unpk77_success) + if(unpk77_success) then + write(*,1100) msg(1:37) +1100 format('Decoded message: ',a37) + else + print*,'Error unpacking message' + endif + + rate=real(91)/real(N) + + write(*,*) "code rate: ",rate + write(*,*) "niter : ",max_iterations + write(*,*) "norder : ",norder + write(*,*) "s : ",s + write(*,*) "K : ",Keff + + msgbits=0 + read(c77,'(77i1)') msgbits(1:77) + write(*,*) 'message' + write(*,'(77i1)') msgbits(1:77) + + call get_crc24(msgbits,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(78:101) + write(*,*) 'message with crc24' + write(*,'(101i1)') msgbits(1:101) + call encode280_101(msgbits,codeword) + call init_random_seed() + call sgran() + + write(*,*) 'codeword' + write(*,'(77i1,1x,24i1,1x,73i1)') codeword + + write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" + do idb = 8,-3,-1 + db=idb/2.0-1.0 + sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No +! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No + ngood=0 + nue=0 + nberr=0 + do itrial=1, ntrials +! Create a realization of a noisy received word + do i=1,N + rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() + enddo + nerr=0 + do i=1,N + if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 + enddo + nberr=nberr+nerr + + rxav=sum(rxdata)/N + rx2av=sum(rxdata*rxdata)/N + rxsig=sqrt(rx2av-rxav*rxav) + rxdata=rxdata/rxsig + if( s .lt. 0 ) then + ss=sigma + else + ss=s + endif + + llr=2.0*rxdata/(ss*ss) + apmask=0 +! max_iterations is max number of belief propagation iterations + call bpdecode280_101(llr,apmask,max_iterations,message101,cw,nharderror,niterations,nchecks) + dmin=0.0 + if( (nharderror .lt. 0) .and. (norder .ge. 0) ) then +! call osd280_101(llr, Keff, apmask, norder, message101, cw, nharderror, dmin) + call decode280_101(llr, Keff, maxosd, norder, apmask, message101, cw, ntype, nharderror, dmin) + endif + + if(nharderror.ge.0) then + n2err=0 + do i=1,N + if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 + enddo + if(n2err.eq.0) then + ngood=ngood+1 + else + nue=nue+1 + endif + endif + enddo +! snr2500=db+10*log10(200.0/116.0/2500.0) + esn0=db+10*log10(rate) + pberr=real(nberr)/(real(ntrials*N)) + write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr + + enddo + +end program ldpcsim280_101 diff --git a/lib/fst280/ldpcsim280_74.f90 b/lib/fst280/ldpcsim280_74.f90 new file mode 100644 index 000000000..8953973e9 --- /dev/null +++ b/lib/fst280/ldpcsim280_74.f90 @@ -0,0 +1,132 @@ +program ldpcsim280_74 + +! End-to-end test of the (280,74)/crc24 encoder and decoders. + + use packjt77 + + parameter(N=280, K=74, M=N-K) + character*8 arg + character*37 msg0,msg + character*77 c77 + character*24 c24 + integer*1 msgbits(74) + integer*1 apmask(280) + integer*1 cw(280) + integer*1 codeword(N),message74(74) + integer ncrc24 + real rxdata(N),llr(N) + real llrd(280) + logical first,unpk77_success + data first/.true./ + + nargs=iargc() + if(nargs.ne.5 .and. nargs.ne.6) then + print*,'Usage: ldpcsim norder maxosd #trials s K [msg]' + print*,'e.g. ldpcsim280_74 3 2 1000 0.85 91 "K9AN K1JT FN20"' + print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' + print*,'niter: is the number of BP iterations.' + print*,'norder: -1 is BP only, norder>=0 is OSD order' + print*,'maxosd: number of calls to OSD' + print*,'K :is the number of message+CRC bits and must be in the range [50,74]' + print*,'WSPR-format message is optional' + return + endif + call getarg(1,arg) + read(arg,*) norder + call getarg(2,arg) + read(arg,*) maxosd + call getarg(3,arg) + read(arg,*) ntrials + call getarg(4,arg) + read(arg,*) s + call getarg(5,arg) + read(arg,*) Keff + msg0='K9AN K1JT FN20 ' + if(nargs.eq.6) call getarg(6,msg0) + call pack77(msg0,i3,n3,c77) + call unpack77(c77,0,msg,unpk77_success) + if(unpk77_success) then + write(*,1100) msg(1:37) +1100 format('Decoded message: ',a37) + else + print*,'Error unpacking message' + endif + + rate=real(64)/real(N) + + write(*,*) "code rate: ",rate + write(*,*) "norder : ",norder + write(*,*) "s : ",s + write(*,*) "K : ",Keff + + msgbits=0 + read(c77,'(50i1)') msgbits(1:50) + write(*,*) 'message' + write(*,'(50i1)') msgbits(1:50) + + msgbits(51:74)=0 + call get_crc24(msgbits,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(51:74) + write(*,*) 'message with crc24' + write(*,'(74i1)') msgbits(1:74) + call encode280_74(msgbits,codeword) + call init_random_seed() + call sgran() + + write(*,*) 'codeword' + write(*,'(50i1,1x,24i1,1x,206i1)') codeword + + write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" + do idb = 2,-2,-1 + db=idb/2.0-1.0 + sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No +! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No + ngood=0 + nue=0 + nberr=0 + do itrial=1, ntrials +! Create a realization of a noisy received word + do i=1,N + rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() + enddo + nerr=0 + do i=1,N + if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 + enddo + nberr=nberr+nerr + + rxav=sum(rxdata)/N + rx2av=sum(rxdata*rxdata)/N + rxsig=sqrt(rx2av-rxav*rxav) + rxdata=rxdata/rxsig + if( s .lt. 0 ) then + ss=sigma + else + ss=s + endif + + llr=2.0*rxdata/(ss*ss) + apmask=0 + call decode280_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharderror,dmin) + + if(nharderror.ge.0) then + n2err=0 + do i=1,N + if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 + enddo + if(n2err.eq.0) then + ngood=ngood+1 + else + nue=nue+1 + endif + endif + enddo +! snr2500=db+10*log10(200.0/116.0/2500.0) + esn0=db+10*log10(rate) + pberr=real(nberr)/(real(ntrials*N)) + write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr + + enddo + +end program ldpcsim280_74 diff --git a/lib/fst280/osd280_101.f90 b/lib/fst280/osd280_101.f90 new file mode 100644 index 000000000..acea3f664 --- /dev/null +++ b/lib/fst280/osd280_101.f90 @@ -0,0 +1,403 @@ +subroutine osd280_101(llr,k,apmask,ndeep,message101,cw,nhardmin,dmin) +! +! An ordered-statistics decoder for the (280,101) code. +! Message payload is 77 bits. Any or all of a 24-bit CRC can be +! used for detecting incorrect codewords. The remaining CRC bits are +! cascaded with the LDPC code for the purpose of improving the +! distance spectrum of the code. +! +! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are +! to be used for bad codeword detection, then the argument k should +! be set to 77+p1. +! +! Valid values for k are in the range [77,101]. +! + character*24 c24 + integer, parameter:: N=280 + integer*1 apmask(N),apmaskr(N) + integer*1, allocatable, save :: gen(:,:) + integer*1, allocatable :: genmrb(:,:),g2(:,:) + integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) + integer*1, allocatable :: r2pat(:) + integer indices(N),nxor(N) + integer*1 cw(N),ce(N),c0(N),hdec(N) + integer*1, allocatable :: decoded(:) + integer*1 message101(101) + integer indx(N) + real llr(N),rx(N),absrx(N) + + logical first,reset + data first/.true./ + save first + + allocate( genmrb(k,N), g2(N,k) ) + allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) + allocate( r2pat(N-k), decoded(k) ) + + if( first ) then ! fill the generator matrix +! +! Create generator matrix for partial CRC cascaded with LDPC code. +! +! Let p2=101-k and p1+p2=24. +! +! The last p2 bits of the CRC24 are cascaded with the LDPC code. +! +! The first p1=k-77 CRC24 bits will be used for error detection. +! + allocate( gen(k,N) ) + gen=0 + do i=1,k + message101=0 + message101(i)=1 + if(i.le.77) then + call get_crc24(message101,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') message101(78:101) + message101(78:k)=0 + endif + call encode280_101(message101,cw) + gen(i,:)=cw + enddo + + first=.false. + endif + + rx=llr + apmaskr=apmask + +! Hard decisions on the received word. + hdec=0 + where(rx .ge. 0) hdec=1 + +! Use magnitude of received symbols as a measure of reliability. + absrx=abs(rx) + call indexx(absrx,N,indx) + +! Re-order the columns of the generator matrix in order of decreasing reliability. + do i=1,N + genmrb(1:k,i)=gen(1:k,indx(N+1-i)) + indices(i)=indx(N+1-i) + enddo + +! Do gaussian elimination to create a generator matrix with the most reliable +! received bits in positions 1:k in order of decreasing reliability (more or less). + do id=1,k ! diagonal element indices + do icol=id,k+20 ! The 20 is ad hoc - beware + iflag=0 + if( genmrb(id,icol) .eq. 1 ) then + iflag=1 + if( icol .ne. id ) then ! reorder column + temp(1:k)=genmrb(1:k,id) + genmrb(1:k,id)=genmrb(1:k,icol) + genmrb(1:k,icol)=temp(1:k) + itmp=indices(id) + indices(id)=indices(icol) + indices(icol)=itmp + endif + do ii=1,k + if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then + genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) + endif + enddo + exit + endif + enddo + enddo + + g2=transpose(genmrb) + +! The hard decisions for the k MRB bits define the order 0 message, m0. +! Encode m0 using the modified generator matrix to find the "order 0" codeword. +! Flip various combinations of bits in m0 and re-encode to generate a list of +! codewords. Return the member of the list that has the smallest Euclidean +! distance to the received word. + + hdec=hdec(indices) ! hard decisions from received symbols + m0=hdec(1:k) ! zero'th order message + absrx=absrx(indices) + rx=rx(indices) + apmaskr=apmaskr(indices) + + call mrbencode101(m0,c0,g2,N,k) + nxor=ieor(c0,hdec) + nhardmin=sum(nxor) + dmin=sum(nxor*absrx) + + cw=c0 + ntotal=0 + nrejected=0 + npre1=0 + npre2=0 + + if(ndeep.eq.0) goto 998 ! norder=0 + if(ndeep.gt.6) ndeep=6 + if( ndeep.eq. 1) then + nord=1 + npre1=0 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.2) then + nord=1 + npre1=1 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.3) then + nord=1 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=14 + elseif(ndeep.eq.4) then + nord=2 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=17 + elseif(ndeep.eq.5) then + nord=3 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=15 + elseif(ndeep.eq.6) then + nord=4 + npre1=1 + npre2=1 + nt=95 + ntheta=12 + ntau=15 + endif + + do iorder=1,nord + misub(1:k-iorder)=0 + misub(k-iorder+1:k)=1 + iflag=k-iorder+1 + do while(iflag .ge.0) + if(iorder.eq.nord .and. npre1.eq.0) then + iend=iflag + else + iend=1 + endif + d1=0. + do n1=iflag,iend,-1 + mi=misub + mi(n1)=1 + if(any(iand(apmaskr(1:k),mi).eq.1)) cycle + ntotal=ntotal+1 + me=ieor(m0,mi) + if(n1.eq.iflag) then + call mrbencode101(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + e2=e2sub + nd1kpt=sum(e2sub(1:nt))+1 + d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) + else + e2=ieor(e2sub,g2(k+1:N,n1)) + nd1kpt=sum(e2(1:nt))+2 + endif + if(nd1kpt .le. ntheta) then + call mrbencode101(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + if(n1.eq.iflag) then + dd=d1+sum(e2sub*absrx(k+1:N)) + else + dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) + endif + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + nd1kptbest=nd1kpt + endif + else + nrejected=nrejected+1 + endif + enddo +! Get the next test error pattern, iflag will go negative +! when the last pattern with weight iorder has been generated. + call nextpat101(misub,k,iorder,iflag) + enddo + enddo + + if(npre2.eq.1) then + reset=.true. + ntotal=0 + do i1=k,1,-1 + do i2=i1-1,1,-1 + ntotal=ntotal+1 + mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) + call boxit101(reset,mi(1:ntau),ntau,ntotal,i1,i2) + enddo + enddo + + ncount2=0 + ntotal2=0 + reset=.true. +! Now run through again and do the second pre-processing rule + misub(1:k-nord)=0 + misub(k-nord+1:k)=1 + iflag=k-nord+1 + do while(iflag .ge.0) + me=ieor(m0,misub) + call mrbencode101(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + do i2=0,ntau + ntotal2=ntotal2+1 + ui=0 + if(i2.gt.0) ui(i2)=1 + r2pat=ieor(e2sub,ui) +778 continue + call fetchit101(reset,r2pat(1:ntau),ntau,in1,in2) + if(in1.gt.0.and.in2.gt.0) then + ncount2=ncount2+1 + mi=misub + mi(in1)=1 + mi(in2)=1 + if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle + me=ieor(m0,mi) + call mrbencode101(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + dd=sum(nxor*absrx) + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + endif + goto 778 + endif + enddo + call nextpat101(misub,k,nord,iflag) + enddo + endif + +998 continue +! Re-order the codeword to [message bits][parity bits] format. + cw(indices)=cw + hdec(indices)=hdec + message101=cw(1:101) + call get_crc24(message101,101,nbadcrc) + if(nbadcrc.ne.0) nhardmin=-nhardmin + + return +end subroutine osd280_101 + +subroutine mrbencode101(me,codeword,g2,N,K) + integer*1 me(K),codeword(N),g2(N,K) +! fast encoding for low-weight test patterns + codeword=0 + do i=1,K + if( me(i) .eq. 1 ) then + codeword=ieor(codeword,g2(1:N,i)) + endif + enddo + return +end subroutine mrbencode101 + +subroutine nextpat101(mi,k,iorder,iflag) + integer*1 mi(k),ms(k) +! generate the next test error pattern + ind=-1 + do i=1,k-1 + if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i + enddo + if( ind .lt. 0 ) then ! no more patterns of this order + iflag=ind + return + endif + ms=0 + ms(1:ind-1)=mi(1:ind-1) + ms(ind)=1 + ms(ind+1)=0 + if( ind+1 .lt. k ) then + nz=iorder-sum(ms) + ms(k-nz+1:k)=1 + endif + mi=ms + do i=1,k ! iflag will point to the lowest-index 1 in mi + if(mi(i).eq.1) then + iflag=i + exit + endif + enddo + return +end subroutine nextpat101 + +subroutine boxit101(reset,e2,ntau,npindex,i1,i2) + integer*1 e2(1:ntau) + integer indexes(5000,2),fp(0:525000),np(5000) + logical reset + common/boxes/indexes,fp,np + + if(reset) then + patterns=-1 + fp=-1 + np=-1 + sc=-1 + indexes=-1 + reset=.false. + endif + + indexes(npindex,1)=i1 + indexes(npindex,2)=i2 + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + + ip=fp(ipat) ! see what's currently stored in fp(ipat) + if(ip.eq.-1) then + fp(ipat)=npindex + else + do while (np(ip).ne.-1) + ip=np(ip) + enddo + np(ip)=npindex + endif + return +end subroutine boxit101 + +subroutine fetchit101(reset,e2,ntau,i1,i2) + integer indexes(5000,2),fp(0:525000),np(5000) + integer lastpat + integer*1 e2(ntau) + logical reset + common/boxes/indexes,fp,np + save lastpat,inext + + if(reset) then + lastpat=-1 + reset=.false. + endif + + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + index=fp(ipat) + + if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices + i1=indexes(index,1) + i2=indexes(index,2) + inext=np(index) + elseif(lastpat.eq.ipat .and. inext.gt.0) then + i1=indexes(inext,1) + i2=indexes(inext,2) + inext=np(inext) + else + i1=-1 + i2=-1 + inext=-1 + endif + lastpat=ipat + return +end subroutine fetchit101 + diff --git a/lib/fst280/osd280_74.f90 b/lib/fst280/osd280_74.f90 new file mode 100644 index 000000000..6f87dd216 --- /dev/null +++ b/lib/fst280/osd280_74.f90 @@ -0,0 +1,403 @@ +subroutine osd280_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin) +! +! An ordered-statistics decoder for the (280,74) code. +! Message payload is 50 bits. Any or all of a 24-bit CRC can be +! used for detecting incorrect codewords. The remaining CRC bits are +! cascaded with the LDPC code for the purpose of improving the +! distance spectrum of the code. +! +! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are +! to be used for bad codeword detection, then the argument k should +! be set to 50+p1. +! +! Valid values for k are in the range [50,74]. +! + character*24 c24 + integer, parameter:: N=280 + integer*1 apmask(N),apmaskr(N) + integer*1, allocatable, save :: gen(:,:) + integer*1, allocatable :: genmrb(:,:),g2(:,:) + integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) + integer*1, allocatable :: r2pat(:) + integer indices(N),nxor(N) + integer*1 cw(N),ce(N),c0(N),hdec(N) + integer*1, allocatable :: decoded(:) + integer*1 message74(74) + integer indx(N) + real llr(N),rx(N),absrx(N) + + logical first,reset + data first/.true./ + save first + + allocate( genmrb(k,N), g2(N,k) ) + allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) + allocate( r2pat(N-k), decoded(k) ) + + if( first ) then ! fill the generator matrix +! +! Create generator matrix for partial CRC cascaded with LDPC code. +! +! Let p2=74-k and p1+p2=24. +! +! The last p2 bits of the CRC24 are cascaded with the LDPC code. +! +! The first p1=k-50 CRC24 bits will be used for error detection. +! + allocate( gen(k,N) ) + gen=0 + do i=1,k + message74=0 + message74(i)=1 + if(i.le.50) then + call get_crc24(message74,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') message74(51:74) + message74(51:k)=0 + endif + call encode280_74(message74,cw) + gen(i,:)=cw + enddo + + first=.false. + endif + + rx=llr + apmaskr=apmask + +! Hard decisions on the received word. + hdec=0 + where(rx .ge. 0) hdec=1 + +! Use magnitude of received symbols as a measure of reliability. + absrx=abs(rx) + call indexx(absrx,N,indx) + +! Re-order the columns of the generator matrix in order of decreasing reliability. + do i=1,N + genmrb(1:k,i)=gen(1:k,indx(N+1-i)) + indices(i)=indx(N+1-i) + enddo + +! Do gaussian elimination to create a generator matrix with the most reliable +! received bits in positions 1:k in order of decreasing reliability (more or less). + do id=1,k ! diagonal element indices + do icol=id,k+20 ! The 20 is ad hoc - beware + iflag=0 + if( genmrb(id,icol) .eq. 1 ) then + iflag=1 + if( icol .ne. id ) then ! reorder column + temp(1:k)=genmrb(1:k,id) + genmrb(1:k,id)=genmrb(1:k,icol) + genmrb(1:k,icol)=temp(1:k) + itmp=indices(id) + indices(id)=indices(icol) + indices(icol)=itmp + endif + do ii=1,k + if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then + genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) + endif + enddo + exit + endif + enddo + enddo + + g2=transpose(genmrb) + +! The hard decisions for the k MRB bits define the order 0 message, m0. +! Encode m0 using the modified generator matrix to find the "order 0" codeword. +! Flip various combinations of bits in m0 and re-encode to generate a list of +! codewords. Return the member of the list that has the smallest Euclidean +! distance to the received word. + + hdec=hdec(indices) ! hard decisions from received symbols + m0=hdec(1:k) ! zero'th order message + absrx=absrx(indices) + rx=rx(indices) + apmaskr=apmaskr(indices) + + call mrbencode74(m0,c0,g2,N,k) + nxor=ieor(c0,hdec) + nhardmin=sum(nxor) + dmin=sum(nxor*absrx) + + cw=c0 + ntotal=0 + nrejected=0 + npre1=0 + npre2=0 + + if(ndeep.eq.0) goto 998 ! norder=0 + if(ndeep.gt.6) ndeep=6 + if( ndeep.eq. 1) then + nord=1 + npre1=0 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.2) then + nord=1 + npre1=1 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.3) then + nord=1 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=14 + elseif(ndeep.eq.4) then + nord=2 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=17 + elseif(ndeep.eq.5) then + nord=3 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=19 + elseif(ndeep.eq.6) then + nord=4 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=19 + endif + + do iorder=1,nord + misub(1:k-iorder)=0 + misub(k-iorder+1:k)=1 + iflag=k-iorder+1 + do while(iflag .ge.0) + if(iorder.eq.nord .and. npre1.eq.0) then + iend=iflag + else + iend=1 + endif + d1=0. + do n1=iflag,iend,-1 + mi=misub + mi(n1)=1 + if(any(iand(apmaskr(1:k),mi).eq.1)) cycle + ntotal=ntotal+1 + me=ieor(m0,mi) + if(n1.eq.iflag) then + call mrbencode74(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + e2=e2sub + nd1kpt=sum(e2sub(1:nt))+1 + d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) + else + e2=ieor(e2sub,g2(k+1:N,n1)) + nd1kpt=sum(e2(1:nt))+2 + endif + if(nd1kpt .le. ntheta) then + call mrbencode74(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + if(n1.eq.iflag) then + dd=d1+sum(e2sub*absrx(k+1:N)) + else + dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) + endif + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + nd1kptbest=nd1kpt + endif + else + nrejected=nrejected+1 + endif + enddo +! Get the next test error pattern, iflag will go negative +! when the last pattern with weight iorder has been generated. + call nextpat74(misub,k,iorder,iflag) + enddo + enddo + + if(npre2.eq.1) then + reset=.true. + ntotal=0 + do i1=k,1,-1 + do i2=i1-1,1,-1 + ntotal=ntotal+1 + mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) + call boxit74(reset,mi(1:ntau),ntau,ntotal,i1,i2) + enddo + enddo + + ncount2=0 + ntotal2=0 + reset=.true. +! Now run through again and do the second pre-processing rule + misub(1:k-nord)=0 + misub(k-nord+1:k)=1 + iflag=k-nord+1 + do while(iflag .ge.0) + me=ieor(m0,misub) + call mrbencode74(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + do i2=0,ntau + ntotal2=ntotal2+1 + ui=0 + if(i2.gt.0) ui(i2)=1 + r2pat=ieor(e2sub,ui) +778 continue + call fetchit74(reset,r2pat(1:ntau),ntau,in1,in2) + if(in1.gt.0.and.in2.gt.0) then + ncount2=ncount2+1 + mi=misub + mi(in1)=1 + mi(in2)=1 + if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle + me=ieor(m0,mi) + call mrbencode74(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + dd=sum(nxor*absrx) + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + endif + goto 778 + endif + enddo + call nextpat74(misub,k,nord,iflag) + enddo + endif + +998 continue +! Re-order the codeword to [message bits][parity bits] format. + cw(indices)=cw + hdec(indices)=hdec + message74=cw(1:74) + call get_crc24(message74,74,nbadcrc) + if(nbadcrc.ne.0) nhardmin=-nhardmin + + return +end subroutine osd280_74 + +subroutine mrbencode74(me,codeword,g2,N,K) + integer*1 me(K),codeword(N),g2(N,K) +! fast encoding for low-weight test patterns + codeword=0 + do i=1,K + if( me(i) .eq. 1 ) then + codeword=ieor(codeword,g2(1:N,i)) + endif + enddo + return +end subroutine mrbencode74 + +subroutine nextpat74(mi,k,iorder,iflag) + integer*1 mi(k),ms(k) +! generate the next test error pattern + ind=-1 + do i=1,k-1 + if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i + enddo + if( ind .lt. 0 ) then ! no more patterns of this order + iflag=ind + return + endif + ms=0 + ms(1:ind-1)=mi(1:ind-1) + ms(ind)=1 + ms(ind+1)=0 + if( ind+1 .lt. k ) then + nz=iorder-sum(ms) + ms(k-nz+1:k)=1 + endif + mi=ms + do i=1,k ! iflag will point to the lowest-index 1 in mi + if(mi(i).eq.1) then + iflag=i + exit + endif + enddo + return +end subroutine nextpat74 + +subroutine boxit74(reset,e2,ntau,npindex,i1,i2) + integer*1 e2(1:ntau) + integer indexes(5000,2),fp(0:525000),np(5000) + logical reset + common/boxes/indexes,fp,np + + if(reset) then + patterns=-1 + fp=-1 + np=-1 + sc=-1 + indexes=-1 + reset=.false. + endif + + indexes(npindex,1)=i1 + indexes(npindex,2)=i2 + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + + ip=fp(ipat) ! see what's currently stored in fp(ipat) + if(ip.eq.-1) then + fp(ipat)=npindex + else + do while (np(ip).ne.-1) + ip=np(ip) + enddo + np(ip)=npindex + endif + return +end subroutine boxit74 + +subroutine fetchit74(reset,e2,ntau,i1,i2) + integer indexes(5000,2),fp(0:525000),np(5000) + integer lastpat + integer*1 e2(ntau) + logical reset + common/boxes/indexes,fp,np + save lastpat,inext + + if(reset) then + lastpat=-1 + reset=.false. + endif + + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + index=fp(ipat) + + if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices + i1=indexes(index,1) + i2=indexes(index,2) + inext=np(index) + elseif(lastpat.eq.ipat .and. inext.gt.0) then + i1=indexes(inext,1) + i2=indexes(inext,2) + inext=np(inext) + else + i1=-1 + i2=-1 + inext=-1 + endif + lastpat=ipat + return +end subroutine fetchit74 + From 5dfb3c781b4a98a6b0cafd7cfea17b9af29421ef Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 16 Jun 2020 12:59:22 -0500 Subject: [PATCH 002/239] Add fst280 files to CMakeLists.txt. Doesn't build yet. --- CMakeLists.txt | 27 +++++++++++++ lib/fst280/gen_fst280wave.f90 | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 lib/fst280/gen_fst280wave.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index ca25c3a08..04776905e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -595,6 +595,21 @@ set (wsjt_FSRCS lib/wqencode.f90 lib/wspr_downsample.f90 lib/zplot9.f90 + lib/fst280/bpdecode280_101.f90 + lib/fst280/bpdecode280_74.f90 + lib/fst280/decode280_101.f90 + lib/fst280/decode280_74.f90 + lib/fst280/encode280_101.f90 + lib/fst280/encode280_74.f90 + lib/fst280/fst280d.f90 + lib/fst280/fst280sim.f90 + lib/fst280/genfst280_wave.f90 + lib/fst280/genfst280.f90 + lib/fst280/get_ft280_bitmetrics.f90 + lib/fst280/ldpcsim280_101.f90 + lib/fst280/ldpcsim280_74.f90 + lib/fst280/osd280_101.f90 + lib/fst280/osd280_74.f90 ) # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit @@ -1351,6 +1366,18 @@ target_link_libraries (ft4sim_mult wsjt_fort wsjt_cxx) add_executable (record_time_signal Audio/tools/record_time_signal.cpp) target_link_libraries (record_time_signal wsjt_cxx wsjt_qtmm wsjt_qt) +add_executable (fst280d lib/fst280/fst280d.f90 wsjtx.rc) +target_link_libraries (fst280d wsjt_fort wsjt_cxx) + +add_executable (fst280sim lib/fst280/fst280sim.f90 wsjtx.rc) +target_link_libraries (fst280sim wsjt_fort wsjt_cxx) + +add_executable (ldpcsim280_101 lib/fst280/ldpcsim280_101.f90 wsjtx.rc) +target_link_libraries (ldpcsim280_101 wsjt_fort wsjt_cxx) + +add_executable (ldpcsim280_74 lib/fst280/ldpcsim280_74.f90 wsjtx.rc) +target_link_libraries (ldpcsim280_74 wsjt_fort wsjt_cxx) + endif(WSJT_BUILD_UTILS) # build the main application diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 new file mode 100644 index 000000000..dcf11ff4d --- /dev/null +++ b/lib/fst280/gen_fst280wave.f90 @@ -0,0 +1,72 @@ +subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0,icmplx,cwave,wave) + + real wave(nwave) + complex cwave(nwave) + real, allocatable, save :: pulse(:) + real, allocatable :: dphi(:) + integer itone(nsym) + logical first + data first/.true./ + save first,twopi,dt,tsym + + if(first) then + allocate( pulse(3*nsps*fsample) ) + twopi=8.0*atan(1.0) + dt=1.0/fsample + tsym=nsps/fsample +! Compute the smoothed frequency-deviation pulse + do i=1,3*nsps + tt=(i-1.5*nsps)/real(nsps) + pulse(i)=gfsk_pulse(2.0,tt) + enddo + first=.false. + endif + +! Compute the smoothed frequency waveform. +! Length = (nsym+2)*nsps samples, zero-padded + allocate( dphi(0:(nsym+2)*nsps-1) ) + dphi_peak=twopi*hmod/real(nsps) + dphi=0.0 + do j=1,nsym + ib=(j-1)*nsps + ie=ib+3*nsps-1 + dphi(ib:ie) = dphi(ib:ie) + dphi_peak*pulse(1:3*nsps)*itone(j) + enddo + +! Calculate and insert the audio waveform + phi=0.0 + dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 + wave=0. + if(icmplx.eq.1) cwave=0. + k=0 + do j=0,(nsym+2)*nsps-1 + k=k+1 + if(icmplx.eq.0) then + wave(k)=sin(phi) + else + cwave(k)=cmplx(cos(phi),sin(phi)) + endif + phi=mod(phi+dphi(j),twopi) + enddo + +! Compute the ramp-up and ramp-down symbols + if(icmplx.eq.0) then + wave(1:nsps/2)=0.0 + wave(nsps/2+1:nsps)=wave(nsps/2+1:nsps) * & + (1.0-cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + k1=(nsym+1)*nsps+1 + wave(k1+nsps/2:)=0.0 + wave(k1:k1+nsps/2-1)=wave(k1:k1+nsps/2-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + else + cwave(1:nsps/2)=0.0 + cwave(nsps/2+1:nsps)=cwave(nsps/2+1:nsps) * & + (1.0-cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + k1=(nsym+1)*nsps+1 + cwave(k1+nsps/2:)=0.0 + cwave(k1:k1+nsps/2-1)=cwave(k1:k1+nsps/2-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + endif + + return +end subroutine gen_fst280wave From e26d6d87156884f6bcfa537f0174b36a32b0c516 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 16 Jun 2020 19:34:14 +0100 Subject: [PATCH 003/239] Typos in source file names --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04776905e..ef9e4dec7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -603,9 +603,9 @@ set (wsjt_FSRCS lib/fst280/encode280_74.f90 lib/fst280/fst280d.f90 lib/fst280/fst280sim.f90 - lib/fst280/genfst280_wave.f90 + lib/fst280/gen_fst280wave.f90 lib/fst280/genfst280.f90 - lib/fst280/get_ft280_bitmetrics.f90 + lib/fst280/get_fst280_bitmetrics.f90 lib/fst280/ldpcsim280_101.f90 lib/fst280/ldpcsim280_74.f90 lib/fst280/osd280_101.f90 From 27e7b7b17b27a1d3b7aad2559ed80940f2fc1749 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 16 Jun 2020 13:38:34 -0500 Subject: [PATCH 004/239] Remove unused variables. --- lib/fst280/encode280_101.f90 | 6 ------ lib/fst280/encode280_74.f90 | 6 ------ 2 files changed, 12 deletions(-) diff --git a/lib/fst280/encode280_101.f90 b/lib/fst280/encode280_101.f90 index 704816355..e908bb607 100644 --- a/lib/fst280/encode280_101.f90 +++ b/lib/fst280/encode280_101.f90 @@ -1,15 +1,9 @@ subroutine encode280_101(message,codeword) - use, intrinsic :: iso_c_binding - use iso_c_binding, only: c_loc,c_size_t - use crc - integer, parameter:: N=280, K=101, M=N-K - character*24 c24 integer*1 codeword(N) integer*1 gen(M,K) integer*1 message(K) integer*1 pchecks(M) - integer*4 ncrc24 include "ldpc_280_101_generator.f90" logical first data first/.true./ diff --git a/lib/fst280/encode280_74.f90 b/lib/fst280/encode280_74.f90 index e923d46f7..a64a57815 100644 --- a/lib/fst280/encode280_74.f90 +++ b/lib/fst280/encode280_74.f90 @@ -1,15 +1,9 @@ subroutine encode280_74(message,codeword) - use, intrinsic :: iso_c_binding - use iso_c_binding, only: c_loc,c_size_t - use crc - integer, parameter:: N=280, K=74, M=N-K - character*24 c24 integer*1 codeword(N) integer*1 gen(M,K) integer*1 message(K) integer*1 pchecks(M) - integer*4 ncrc24 include "ldpc_280_74_generator.f90" logical first data first/.true./ From 3424dd7aa1b3942d27f1215515546e2b323258d1 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 16 Jun 2020 19:34:14 +0100 Subject: [PATCH 005/239] Typos in source file names and missed file --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04776905e..95ef7d9c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -603,13 +603,14 @@ set (wsjt_FSRCS lib/fst280/encode280_74.f90 lib/fst280/fst280d.f90 lib/fst280/fst280sim.f90 - lib/fst280/genfst280_wave.f90 + lib/fst280/gen_fst280wave.f90 lib/fst280/genfst280.f90 - lib/fst280/get_ft280_bitmetrics.f90 + lib/fst280/get_fst280_bitmetrics.f90 lib/fst280/ldpcsim280_101.f90 lib/fst280/ldpcsim280_74.f90 lib/fst280/osd280_101.f90 lib/fst280/osd280_74.f90 + lib/fst280/get_crc24.f90 ) # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit From 18776df8667b9983d8e437b069d7df28cb74fb2a Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 16 Jun 2020 13:40:52 -0500 Subject: [PATCH 006/239] Add missing get_crc24.f90 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef9e4dec7..74289b285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -603,6 +603,7 @@ set (wsjt_FSRCS lib/fst280/encode280_74.f90 lib/fst280/fst280d.f90 lib/fst280/fst280sim.f90 + lib/fst280/get_crc24.f90 lib/fst280/gen_fst280wave.f90 lib/fst280/genfst280.f90 lib/fst280/get_fst280_bitmetrics.f90 From 725933ddca59e0c253f42a85879819ecef060aa5 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 16 Jun 2020 14:58:08 -0400 Subject: [PATCH 007/239] Initial commit with some GUI features for FST280 and FS280W. --- widgets/mainwindow.cpp | 37 ++++++++++++++++++++++++++++++++++++- widgets/mainwindow.h | 2 ++ widgets/mainwindow.ui | 28 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 0ed391faa..03144f51d 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -422,7 +422,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, add_child_to_event_filter (this); ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); - ui->sbTR->values ({5, 10, 15, 30}); + ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -573,6 +573,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, on_EraseButton_clicked (); QActionGroup* modeGroup = new QActionGroup(this); + ui->actionFST280->setActionGroup(modeGroup); + ui->actionFST280W->setActionGroup(modeGroup); ui->actionFT4->setActionGroup(modeGroup); ui->actionFT8->setActionGroup(modeGroup); ui->actionJT9->setActionGroup(modeGroup); @@ -2317,6 +2319,10 @@ void MainWindow::setup_status_bar (bool vhf) } else if ("FT4" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff0099}"); } else if ("FT8" == m_mode) { + mode_label.setStyleSheet ("QLabel{background-color: #ff6699}"); + } else if ("FST280" == m_mode) { + mode_label.setStyleSheet ("QLabel{background-color: #99ff66}"); + } else if ("FST280W" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #6699ff}"); } else if ("FreqCal" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff9933}"); @@ -5812,6 +5818,33 @@ void MainWindow::displayWidgets(qint64 n) genStdMsgs (m_rpt, true); } +void MainWindow::on_actionFST280_triggered() +{ + m_mode="FST280"; + m_modeTx="FST280"; + ui->actionFST280->setChecked(true); + WSPR_config(false); +// 012345678901234567890123456789012 + displayWidgets(nWidgets("111011000000111100010000000000000")); + bool bVHF=m_config.enable_VHF_features(); + setup_status_bar (bVHF); + ui->sbSubmode->setMaximum(3); + statusChanged(); +} + +void MainWindow::on_actionFST280W_triggered() +{ + m_mode="FST280W"; + m_modeTx="FST280W"; + WSPR_config(true); + ui->actionFST280W->setChecked(true); +// 012345678901234567890123456789012 + displayWidgets(nWidgets("000000000000000001010000000000000")); + bool bVHF=m_config.enable_VHF_features(); + setup_status_bar (bVHF); + statusChanged(); +} + void MainWindow::on_actionFT4_triggered() { m_mode="FT4"; @@ -8994,6 +9027,8 @@ void MainWindow::on_pbBestSP_clicked() void MainWindow::set_mode (QString const& mode) { if ("FT4" == mode) on_actionFT4_triggered (); + else if ("FST280" == mode) on_actionFST280_triggered (); + else if ("FST280W" == mode) on_actionFST280W_triggered (); else if ("FT8" == mode) on_actionFT8_triggered (); else if ("JT4" == mode) on_actionJT4_triggered (); else if ("JT9" == mode) on_actionJT9_triggered (); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 6da871b37..887e59c15 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -204,6 +204,8 @@ private slots: void on_actionJT4_triggered(); void on_actionFT4_triggered(); void on_actionFT8_triggered(); + void on_actionFST280_triggered(); + void on_actionFST280W_triggered(); void on_TxFreqSpinBox_valueChanged(int arg1); void on_actionSave_decoded_triggered(); void on_actionQuickDecode_toggled (bool); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index ac2b23bcb..88233bb8e 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2842,6 +2842,8 @@ list. The list can be maintained in Settings (F2). Mode + + @@ -3476,6 +3478,32 @@ list. The list can be maintained in Settings (F2). FT4 + + + true + + + FST280 + + + + + FST280-W + + + + + FT280W + + + + + true + + + FST280W + + From ed021dadfaed012d27dbfd648d229c339666463e Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 16 Jun 2020 14:30:00 -0500 Subject: [PATCH 008/239] fix what I broke in the last commit. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd3a1352c..95ef7d9c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -603,7 +603,7 @@ set (wsjt_FSRCS lib/fst280/encode280_74.f90 lib/fst280/fst280d.f90 lib/fst280/fst280sim.f90 - lib/fst280/gen_fst280_wave.f90 + lib/fst280/gen_fst280wave.f90 lib/fst280/genfst280.f90 lib/fst280/get_fst280_bitmetrics.f90 lib/fst280/ldpcsim280_101.f90 From 4f802cae84ecca51d070d93ad6368a69dddfe101 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 16 Jun 2020 15:56:15 -0400 Subject: [PATCH 009/239] More work toward implementing GUI features for FST280 and FST280W. --- models/Modes.cpp | 4 +++- models/Modes.hpp | 2 ++ widgets/mainwindow.cpp | 12 +++++++++++- widgets/mainwindow.ui | 23 +++++++++++++++++++++-- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/models/Modes.cpp b/models/Modes.cpp index 838585b2a..1b1febfa8 100644 --- a/models/Modes.cpp +++ b/models/Modes.cpp @@ -24,7 +24,9 @@ namespace "QRA64", "FreqCal", "FT8", - "FT4" + "FT4", + "FST280", + "FST280W" }; std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]); } diff --git a/models/Modes.hpp b/models/Modes.hpp index fea55e4d4..c98b1c6fb 100644 --- a/models/Modes.hpp +++ b/models/Modes.hpp @@ -50,6 +50,8 @@ public: FreqCal, FT8, FT4, + FST280, + FST280W, MODES_END_SENTINAL_AND_COUNT // this must be last }; Q_ENUM (Mode) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 03144f51d..778ca321a 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -423,6 +423,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); + ui->sbTR_FST280W->values ({120, 300}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -5828,6 +5829,9 @@ void MainWindow::on_actionFST280_triggered() displayWidgets(nWidgets("111011000000111100010000000000000")); bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); + m_TRperiod = ui->sbTR->value (); + ui->sbTR->setMinimum(15); + ui->sbTR->setMaximum(300); ui->sbSubmode->setMaximum(3); statusChanged(); } @@ -5839,9 +5843,14 @@ void MainWindow::on_actionFST280W_triggered() WSPR_config(true); ui->actionFST280W->setChecked(true); // 012345678901234567890123456789012 - displayWidgets(nWidgets("000000000000000001010000000000000")); + displayWidgets(nWidgets("000001000000000001010000000000000")); bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); + m_TRperiod = ui->sbTR->value (); + ui->band_hopping_group_box->setVisible(false); + ui->sbTR->setMinimum(120); + ui->sbTR->setMaximum(300); + ui->sbSubmode->setMaximum(3); statusChanged(); } @@ -6464,6 +6473,7 @@ void MainWindow::WSPR_config(bool b) ui->label_7->setVisible(!b and ui->cbMenus->isChecked()); ui->logQSOButton->setVisible(!b); ui->DecodeButton->setEnabled(!b); + ui->band_hopping_group_box->setVisible(true); if(b and (m_mode!="Echo")) { QString t="UTC dB DT Freq Drift Call Grid dBm "; if(m_config.miles()) t += " mi"; diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 88233bb8e..ccce59e4c 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -1039,7 +1039,7 @@ QPushButton[state="ok"] { - 0 + 1 @@ -1608,7 +1608,7 @@ When not checked you can view the calibration results. QTabWidget::Triangular - 0 + 1 @@ -2590,6 +2590,25 @@ list. The list can be maintained in Settings (F2). + + + + Qt::AlignCenter + + + s + + + T/R + + + 120 + + + 300 + + + From abcb7c3ff58ebb9c70c26eaf24610a5de7535086 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 16 Jun 2020 16:33:15 -0400 Subject: [PATCH 010/239] Update one more file name, and the *.f90 references to 'include' it. --- lib/fst280/fst280_params.f90 | 8 ++++++++ lib/fst280/fst280d.f90 | 4 ++-- lib/fst280/fst280sim.f90 | 2 +- lib/fst280/genfst280.f90 | 4 ++-- lib/fst280/get_fst280_bitmetrics.f90 | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 lib/fst280/fst280_params.f90 diff --git a/lib/fst280/fst280_params.f90 b/lib/fst280/fst280_params.f90 new file mode 100644 index 000000000..e541beeed --- /dev/null +++ b/lib/fst280/fst280_params.f90 @@ -0,0 +1,8 @@ +! FT4S280 +! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols + +parameter (KK=77) !Information bits (77 + CRC24) +parameter (ND=140) !Data symbols +parameter (NS=24) !Sync symbols +parameter (NN=NS+ND) !Sync and data symbols (164) +parameter (NN2=NS+ND+2) !Total channel symbols (166) diff --git a/lib/fst280/fst280d.f90 b/lib/fst280/fst280d.f90 index edfee81f7..8442b18d9 100644 --- a/lib/fst280/fst280d.f90 +++ b/lib/fst280/fst280d.f90 @@ -3,7 +3,7 @@ program fst280d ! Decode fst280 data read from *.c2 or *.wav files. use packjt77 - include 'ft4s280_params.f90' + include 'fst280_params.f90' character arg*8,infile*80,fname*16,datetime*11 ! character ch1*1,ch4*4,cseq*31 ! character*22 decodes(100) @@ -336,7 +336,7 @@ subroutine sync_fst280(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) ! Compute sync power for a complex, downsampled FST280 signal. - include 'ft4s280_params.f90' + include 'fst280_params.f90' complex cd0(0:np-1) complex, allocatable, save :: csync(:) complex, allocatable, save :: csynct(:) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index 72026344b..70c6e5cb6 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -4,7 +4,7 @@ program fst280sim use wavhdr use packjt77 - include 'ft4s280_params.f90' !Set various constants + include 'fst280_params.f90' !Set various constants type(hdr) h !Header for .wav file character arg*12,fname*17 character msg37*37,msgsent37*37,c77*77 diff --git a/lib/fst280/genfst280.f90 b/lib/fst280/genfst280.f90 index e074b5080..a0adf5611 100644 --- a/lib/fst280/genfst280.f90 +++ b/lib/fst280/genfst280.f90 @@ -13,7 +13,7 @@ subroutine genfst280(msg0,ichk,msgsent,msgbits,i4tone,iwspr) ! Message duration: TxT = 164*8400/12000 = 114.8 s use packjt77 - include 'ft4s280_params.f90' + include 'fst280_params.f90' character*37 msg0 character*37 message !Message to be generated character*37 msgsent !Message as it will be received @@ -68,7 +68,7 @@ subroutine genfst280(msg0,ichk,msgsent,msgbits,i4tone,iwspr) msgsent='*** bad message *** ' go to 999 - entry get_ft4s280_tones_from_bits(msgbits,i4tone,iwspr) + entry get_fst280_tones_from_bits(msgbits,i4tone,iwspr) 2 continue diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index a50088f66..b5bcf8a10 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -1,6 +1,6 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) - include 'ft4s280_params.f90' + include 'fst280_params.f90' complex cd(0:NN*nss-1) complex cs(0:3,NN) complex csymb(nss) From 0e3ff2688a6ea6c618a05fc5dfe429e207a4ed0d Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 16 Jun 2020 16:59:40 -0400 Subject: [PATCH 011/239] Further progress toward activating FST280 and FST280W in the GUI. --- lib/fst280/fst280_params.f90 | 16 ++++---- lib/fst280/ft4s280_params.f90 | 8 ---- widgets/mainwindow.cpp | 71 ++++++++++------------------------- widgets/mainwindow.h | 1 - 4 files changed, 28 insertions(+), 68 deletions(-) delete mode 100644 lib/fst280/ft4s280_params.f90 diff --git a/lib/fst280/fst280_params.f90 b/lib/fst280/fst280_params.f90 index e541beeed..dc1519160 100644 --- a/lib/fst280/fst280_params.f90 +++ b/lib/fst280/fst280_params.f90 @@ -1,8 +1,8 @@ -! FT4S280 -! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols - -parameter (KK=77) !Information bits (77 + CRC24) -parameter (ND=140) !Data symbols -parameter (NS=24) !Sync symbols -parameter (NN=NS+ND) !Sync and data symbols (164) -parameter (NN2=NS+ND+2) !Total channel symbols (166) +! FT4S280 +! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols + +parameter (KK=77) !Information bits (77 + CRC24) +parameter (ND=140) !Data symbols +parameter (NS=24) !Sync symbols +parameter (NN=NS+ND) !Sync and data symbols (164) +parameter (NN2=NS+ND+2) !Total channel symbols (166) diff --git a/lib/fst280/ft4s280_params.f90 b/lib/fst280/ft4s280_params.f90 deleted file mode 100644 index dc1519160..000000000 --- a/lib/fst280/ft4s280_params.f90 +++ /dev/null @@ -1,8 +0,0 @@ -! FT4S280 -! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols - -parameter (KK=77) !Information bits (77 + CRC24) -parameter (ND=140) !Data symbols -parameter (NS=24) !Sync symbols -parameter (NN=NS+ND) !Sync and data symbols (164) -parameter (NN2=NS+ND+2) !Total channel symbols (166) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 778ca321a..935866bb3 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1316,8 +1316,6 @@ void MainWindow::fixStop() m_hsymStop=179; if(m_mode=="WSPR") { m_hsymStop=396; - } else if(m_mode=="WSPR-LF") { - m_hsymStop=813; } else if(m_mode=="Echo") { m_hsymStop=9; } else if (m_mode=="JT4"){ @@ -1533,26 +1531,11 @@ void MainWindow::dataSink(qint64 frames) m_cmndP1 << depth_args << "-a" << QDir::toNativeSeparators (m_config.writeable_data_dir ().absolutePath()) << m_path; } else { - // if(m_mode=="WSPR-LF") - // { - // m_cmndP1 << degrade << t2 << "-a" - // << QDir::toNativeSeparators (m_config.writeable_data_dir ().absolutePath()) - // << m_fnameWE + ".wav"; - // } - // else - { - m_cmndP1 << depth_args << "-a" - << QDir::toNativeSeparators (m_config.writeable_data_dir ().absolutePath()) - << t2 << m_fnameWE + ".wav"; - } + m_cmndP1 << depth_args << "-a" + << QDir::toNativeSeparators (m_config.writeable_data_dir ().absolutePath()) + << t2 << m_fnameWE + ".wav"; } - // QString t3=cmnd; - // int i1=cmnd.indexOf("/wsprd "); - // cmnd=t3.mid(0,i1+7) + t3.mid(i1+7); - -// if(m_mode=="WSPR-LF") cmnd=cmnd.replace("/wsprd ","/wspr_fsk8d "+degrade+t2); if (ui) ui->DecodeButton->setChecked (true); - // m_cmndP1=QDir::toNativeSeparators(cmnd); p1Timer.start(1000); m_decoderBusy = true; statusUpdate (); @@ -1563,14 +1546,8 @@ void MainWindow::dataSink(qint64 frames) void MainWindow::startP1() { - // if (m_mode=="WSPR-LF") - // { - // p1.start (QDir::toNativeSeparators (QDir {QApplication::applicationDirPath ()}.absoluteFilePath ("wspr_fsk8d")), m_cmndP1); - // } - // else - { - p1.start (QDir::toNativeSeparators (QDir {QApplication::applicationDirPath ()}.absoluteFilePath ("wsprd")), m_cmndP1); - } + // if(WSPR-LF) ... was here + p1.start (QDir::toNativeSeparators (QDir {QApplication::applicationDirPath ()}.absoluteFilePath ("wsprd")), m_cmndP1); } QString MainWindow::save_wave_file (QString const& name, short const * data, int samples, @@ -3561,9 +3538,15 @@ void MainWindow::guiUpdate() if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4 if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9 if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65 - if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 - if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR - if(m_modeTx=="WSPR-LF") txDuration=2.0 + 114*24576/12000.0; // WSPR-LF + if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 + if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR + if(m_modeTx=="FST280" or m_mode=="FST280W") { //FST280, FST280W + if(m_TRperiod==15) txDuration=1.0 + 164*800/12000.0; + if(m_TRperiod==30) txDuration=1.0 + 164*1680/12000.0; + if(m_TRperiod==60) txDuration=1.0 + 164*4000/12000.0; + if(m_TRperiod==120) txDuration=1.0 + 164*8400/12000.0; + if(m_TRperiod==300) txDuration=1.0 + 164*2150500/12000.0; + } if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 } @@ -3834,8 +3817,6 @@ void MainWindow::guiUpdate() &m_currentMessageType, 22, 22); if(m_modeTx=="WSPR") genwspr_(message, msgsent, const_cast (itone), 22, 22); -// if(m_modeTx=="WSPR-LF") genwspr_fsk8_(message, msgsent, const_cast (itone), -// 22, 22); if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4") { char MyCall[6]; char MyGrid[6]; @@ -3896,6 +3877,10 @@ void MainWindow::guiUpdate() gen_ft4wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave, foxcom_.wave,&icmplx,&nwave); } + if(m_modeTx=="FST280" or m_modeTx=="FST280W") { + // call genfst280() + // call gen_fst280wave() + } if(SpecOp::EU_VHF==m_config.special_op_id()) { if(m_ntx==2) m_xSent=ui->tx2->text().right(13); @@ -6353,23 +6338,6 @@ void MainWindow::on_actionWSPR_triggered() statusChanged(); } -void MainWindow::on_actionWSPR_LF_triggered() -{ - on_actionWSPR_triggered(); - m_mode="WSPR-LF"; - switch_mode (Modes::WSPR); - m_modeTx="WSPR-LF"; - m_TRperiod=240.0; - m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe - m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe - m_hsymStop=813; - m_toneSpacing=12000.0/24576.0; - setup_status_bar (false); - ui->actionWSPR_LF->setChecked(true); - m_wideGraph->setPeriod(m_TRperiod,m_nsps); - statusChanged(); -} - void MainWindow::on_actionEcho_triggered() { on_actionJT4_triggered(); @@ -9049,7 +9017,8 @@ void MainWindow::set_mode (QString const& mode) else if ("ISCAT" == mode) on_actionISCAT_triggered (); else if ("MSK144" == mode) on_actionMSK144_triggered (); else if ("WSPR" == mode) on_actionWSPR_triggered (); - else if ("WSPR-LF" == mode) on_actionWSPR_LF_triggered (); + else if ("FST280" == mode) on_actionFST280_triggered (); + else if ("FST280W" == mode) on_actionFST280W_triggered (); else if ("Echo" == mode) on_actionEcho_triggered (); } diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 887e59c15..779d76da4 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -278,7 +278,6 @@ private slots: 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(int); void on_sbTxPercent_valueChanged(int n); From 919702f6a7d88574c74d11c3bf78f31b49bc5c05 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 16 Jun 2020 17:27:49 -0400 Subject: [PATCH 012/239] Add suggested frequencies for FST280 and FSt280W. --- models/FrequencyList.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index c0170a499..def2e6ec4 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -46,16 +46,21 @@ namespace {20000000, Modes::FreqCal, IARURegions::ALL}, {136000, Modes::WSPR, IARURegions::ALL}, + {136000, Modes::FST280W, IARURegions::ALL}, {136130, Modes::JT65, IARURegions::ALL}, {136130, Modes::JT9, IARURegions::ALL}, + {136130, Modes::FST280, IARURegions::ALL}, {474200, Modes::JT65, IARURegions::ALL}, {474200, Modes::JT9, IARURegions::ALL}, + {474200, Modes::FST280, IARURegions::ALL}, {474200, Modes::WSPR, IARURegions::ALL}, - + {474200, Modes::FST280W, IARURegions::ALL}, + {1836600, Modes::WSPR, IARURegions::ALL}, {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations {1839000, Modes::JT9, IARURegions::ALL}, + {1839000, Modes::FST280, IARURegions::ALL}, {1840000, Modes::FT8, IARURegions::ALL}, // Band plans (all USB dial unless stated otherwise) @@ -87,6 +92,7 @@ namespace // {3570000, Modes::JT65, IARURegions::ALL}, // JA compatible {3572000, Modes::JT9, IARURegions::ALL}, + {3572000, Modes::FST280, IARURegions::ALL}, {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out {3575000, Modes::FT4, IARURegions::ALL}, // provisional @@ -127,6 +133,7 @@ namespace {7074000, Modes::FT8, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL}, + {7078000, Modes::FST280, IARURegions::ALL}, {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved // up 500Hz to clear // W1AW code practice QRG @@ -161,6 +168,7 @@ namespace {10138000, Modes::JT65, IARURegions::ALL}, {10138700, Modes::WSPR, IARURegions::ALL}, {10140000, Modes::JT9, IARURegions::ALL}, + {10140000, Modes::FST280, IARURegions::ALL}, {10140000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -204,6 +212,7 @@ namespace {14074000, Modes::FT8, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL}, + {14078000, Modes::FST280, IARURegions::ALL}, {14080000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -236,24 +245,28 @@ namespace {18100000, Modes::FT8, IARURegions::ALL}, {18102000, Modes::JT65, IARURegions::ALL}, {18104000, Modes::JT9, IARURegions::ALL}, + {18104000, Modes::FST280, IARURegions::ALL}, {18104000, Modes::FT4, IARURegions::ALL}, // provisional {18104600, Modes::WSPR, IARURegions::ALL}, {21074000, Modes::FT8, IARURegions::ALL}, {21076000, Modes::JT65, IARURegions::ALL}, {21078000, Modes::JT9, IARURegions::ALL}, + {21078000, Modes::FST280, IARURegions::ALL}, {21094600, Modes::WSPR, IARURegions::ALL}, {21140000, Modes::FT4, IARURegions::ALL}, {24915000, Modes::FT8, IARURegions::ALL}, {24917000, Modes::JT65, IARURegions::ALL}, {24919000, Modes::JT9, IARURegions::ALL}, + {24919000, Modes::FST280, IARURegions::ALL}, {24919000, Modes::FT4, IARURegions::ALL}, // provisional {24924600, Modes::WSPR, IARURegions::ALL}, {28074000, Modes::FT8, IARURegions::ALL}, {28076000, Modes::JT65, IARURegions::ALL}, {28078000, Modes::JT9, IARURegions::ALL}, + {28078000, Modes::FST280, IARURegions::ALL}, {28124600, Modes::WSPR, IARURegions::ALL}, {28180000, Modes::FT4, IARURegions::ALL}, @@ -267,6 +280,7 @@ namespace {50293000, Modes::WSPR, IARURegions::R3}, {50310000, Modes::JT65, IARURegions::ALL}, {50312000, Modes::JT9, IARURegions::ALL}, + {50312000, Modes::FST280, IARURegions::ALL}, {50313000, Modes::FT8, IARURegions::ALL}, {50318000, Modes::FT4, IARURegions::ALL}, // provisional {50323000, Modes::FT8, IARURegions::ALL}, From af9f7b21c0404eab42fd4a793acb1bc67ee7e0a4 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 10:56:18 -0400 Subject: [PATCH 013/239] Starting to implement FST280 decoder. Make Rx sequences behave as desired. --- CMakeLists.txt | 1 + lib/decoder.f90 | 13 +++++++++++++ widgets/mainwindow.cpp | 41 ++++++++++++++--------------------------- widgets/mainwindow.ui | 4 ++-- wsjtx.pro | 1 + 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95ef7d9c5..f8986e5c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -369,6 +369,7 @@ set (wsjt_FSRCS lib/jt65_mod.f90 lib/ft8_decode.f90 lib/ft4_decode.f90 + lib/fst280_decode.f90 lib/jt9_decode.f90 lib/options.f90 lib/packjt.f90 diff --git a/lib/decoder.f90 b/lib/decoder.f90 index c7b3585b5..61ff4163d 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -8,6 +8,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) use jt9_decode use ft8_decode use ft4_decode + use fst280_decode include 'jt9com.f90' include 'timer_common.inc' @@ -32,6 +33,10 @@ subroutine multimode_decoder(ss,id2,params,nfsample) integer :: decoded end type counting_ft4_decoder + type, extends(fst280_decoder) :: counting_fst280_decoder + integer :: decoded + end type counting_fst280_decoder + real ss(184,NSMAX) logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,ex integer*2 id2(NTMAX*12000) @@ -48,6 +53,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) type(counting_jt9_decoder) :: my_jt9 type(counting_ft8_decoder) :: my_ft8 type(counting_ft4_decoder) :: my_ft4 + type(counting_fst280_decoder) :: my_fst280 !cast C character arrays to Fortran character strings datetime=transfer(params%datetime, datetime) @@ -62,6 +68,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) my_jt9%decoded = 0 my_ft8%decoded = 0 my_ft4%decoded = 0 + my_fst280%decoded = 0 ! For testing only: return Rx messages stored in a file as decodes inquire(file='rx_messages.txt',exist=ex) @@ -180,6 +187,12 @@ subroutine multimode_decoder(ss,id2,params,nfsample) go to 800 endif + if(params%nmode.eq.280) then +! We're in FST280/FST280W mode + print*,'FST280/FST280W' + go to 800 + endif + rms=sqrt(dot_product(float(id2(300000:310000)), & float(id2(300000:310000)))/10000.0) if(rms.lt.2.0) go to 800 diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 935866bb3..1b1b2a685 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1336,7 +1336,13 @@ void MainWindow::fixStop() m_hsymStop=50; } else if (m_mode=="FT4") { m_hsymStop=21; -} + } else if(m_mode=="FST280" or m_mode=="FST280W") { + if(m_TRperiod==15) m_hsymStop=51; + if(m_TRperiod==30) m_hsymStop=95; + if(m_TRperiod==60) m_hsymStop=205; + if(m_TRperiod==120) m_hsymStop=414; + if(m_TRperiod==300) m_hsymStop=1036; + } } //-------------------------------------------------------------- dataSink() @@ -1368,7 +1374,6 @@ void MainWindow::dataSink(qint64 frames) // Get power, spectrum, and ihsym int trmin=m_TRperiod/60.0; -// int k (frames - 1); dec_data.params.nfa=m_wideGraph->nStartFreq(); dec_data.params.nfb=m_wideGraph->Fmax(); int nsps=m_nsps; @@ -1388,6 +1393,7 @@ void MainWindow::dataSink(qint64 frames) if(m_mode=="MSK144") return; fixStop(); + qDebug() << "aa" << m_hsymStop << m_ihsym << m_TRperiod; if (m_mode == "FreqCal" // only calculate after 1st chunk, also skip chunk where rig // changed frequency @@ -1485,9 +1491,9 @@ void MainWindow::dataSink(qint64 frames) m_dateTime = now.toString ("yyyy-MMM-dd hh:mm"); if(!m_mode.startsWith ("WSPR")) decode(); //Start decoder if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return; - if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR")) { //Always save unless "Save None"; may delete later - if(m_mode=="FT8" or m_mode=="FT4") { +// if(m_mode=="FT8" or m_mode=="FT4") { + if(m_TRperiod < 60) { int n=fmod(double(now.time().second()),m_TRperiod); if(n<(m_TRperiod/2)) n=n+m_TRperiod; auto const& period_start=now.addSecs(-n); @@ -1516,7 +1522,6 @@ void MainWindow::dataSink(qint64 frames) if (err!=0) MessageBox::warning_message (this, tr ("Error saving c2 file"), c2name); } } - if(m_mode.startsWith ("WSPR")) { QStringList t2; QStringList depth_args; @@ -2861,13 +2866,6 @@ void MainWindow::decode() //decode() if( m_dateTimeLastTX.isValid () ) { qint64 isecs_since_tx = m_dateTimeLastTX.secsTo(now); dec_data.params.lapcqonly= (isecs_since_tx > 300); -// QTextStream(stdout) << "last tx " << isecs_since_tx -// #if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0) -// << Qt::endl -// #else -// << endl -// #endif -// ; } else { m_dateTimeLastTX = now.addSecs(-900); dec_data.params.lapcqonly=true; @@ -2875,7 +2873,6 @@ void MainWindow::decode() //decode() if( m_diskData ) { dec_data.params.lapcqonly=false; } - m_msec0=QDateTime::currentMSecsSinceEpoch(); if(!m_dataAvailable or m_TRperiod==0.0) return; ui->DecodeButton->setChecked (true); @@ -2961,6 +2958,7 @@ void MainWindow::decode() //decode() dec_data.params.nmode=5; m_BestCQpriority=""; } + if(m_mode=="FST280") dec_data.params.nmode=280; dec_data.params.ntrperiod=m_TRperiod; dec_data.params.nsubmode=m_nSubMode; if(m_mode=="QRA64") dec_data.params.nsubmode=100 + m_nSubMode; @@ -3036,18 +3034,6 @@ void MainWindow::decode() //decode() mem_jt9->lock (); memcpy(to, from, qMin(mem_jt9->size(), size)); mem_jt9->unlock (); - -/* - auto now = QDateTime::currentDateTimeUtc(); - double tsec = fmod(double(now.toMSecsSinceEpoch()),86400000.0)/1000.0; - double tseq = fmod(double(now.toMSecsSinceEpoch()),1000.0*m_TRperiod)/1000.0; - if(tseq < 0.5*m_TRperiod) tseq+= m_TRperiod; - if(m_ihsym==m_earlyDecode) qDebug() << ""; - QString t; - t = t.asprintf("aa release_jt9 %11.3f %5d %5d %7.3f ",tsec,m_ihsym,m_ihsym,tseq); - qDebug().noquote() << t << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz"); -*/ - to_jt9(m_ihsym,1,-1); //Send m_ihsym to jt9[.exe] and start decoding decodeBusy(true); } @@ -4676,7 +4662,6 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie if(SpecOp::EU_VHF==m_config.special_op_id() and message_words.at(1).contains(m_baseCall) and (!message_words.at(2).contains(qso_partner_base_call)) and (!m_bDoubleClicked)) { -// qDebug() << "aa" << "Ignoring:" << message.string().mid(24); return; } @@ -5806,6 +5791,7 @@ void MainWindow::displayWidgets(qint64 n) void MainWindow::on_actionFST280_triggered() { + on_actionJT65_triggered(); m_mode="FST280"; m_modeTx="FST280"; ui->actionFST280->setChecked(true); @@ -5818,6 +5804,7 @@ void MainWindow::on_actionFST280_triggered() ui->sbTR->setMinimum(15); ui->sbTR->setMaximum(300); ui->sbSubmode->setMaximum(3); + on_sbTR_valueChanged(ui->sbTR->value()); statusChanged(); } @@ -7404,7 +7391,7 @@ void::MainWindow::VHF_features_enabled(bool b) void MainWindow::on_sbTR_valueChanged(int value) { // if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode; - if(m_bFastMode or m_mode=="FreqCal") { + if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST280" or m_mode=="FST280W") { m_TRperiod = value; m_fastGraph->setTRPeriod (value); m_modulator->setTRPeriod (value); // TODO - not thread safe diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index ccce59e4c..9b07c7714 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -1039,7 +1039,7 @@ QPushButton[state="ok"] { - 1 + 0 @@ -1608,7 +1608,7 @@ When not checked you can view the calibration results. QTabWidget::Triangular - 1 + 2 diff --git a/wsjtx.pro b/wsjtx.pro index 3248fefd7..02a69d33c 100644 --- a/wsjtx.pro +++ b/wsjtx.pro @@ -53,6 +53,7 @@ include(item_delegates/item_delegates.pri) include(logbook/logbook.pri) include(widgets/widgets.pri) include(Decoder/decodedtext.pri) +include(Detector/Detector.pri) SOURCES += \ Radio.cpp NetworkServerLookup.cpp revision_utils.cpp \ From 57a2b7d565b64d79c729438af7099ac3337024d5 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 17 Jun 2020 10:44:29 -0500 Subject: [PATCH 014/239] Make hmod an integer everywhere. Add h=8. Increase nominal nss to 40*h Sa/symbol. --- lib/fst280/fst280d.f90 | 49 +++++++++++++++------------- lib/fst280/fst280sim.f90 | 4 ++- lib/fst280/gen_fst280wave.f90 | 1 + lib/fst280/get_fst280_bitmetrics.f90 | 1 + 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/lib/fst280/fst280d.f90 b/lib/fst280/fst280d.f90 index edfee81f7..7ec778727 100644 --- a/lib/fst280/fst280d.f90 +++ b/lib/fst280/fst280d.f90 @@ -19,21 +19,21 @@ program fst280d real llr(280),llra(280),llrb(280),llrc(280),llrd(280) real candidates(100,3) real bitmetrics(328,4) - integer ihdr(11) + integer hmod,ihdr(11) integer*2, allocatable :: iwave(:) integer*1 apmask(280),cw(280) integer*1 hbits(328) integer*1 message101(101),message74(74) logical badsync,unpk77_success - hmod=1.0 + hmod=1 Keff=91 ndeep=3 iwspr=0 nargs=iargc() if(nargs.lt.1) then - print*,'Usage: fst280d [-a ] [-f fMHz] [-h hmod] [-k Keff] file1 [file2 ...]' + print*,'Usage: fst280d [-a ] [-f fMHz] [-h hmod] [-k Keff] [-d depth] [-t t/r type] file1 [file2 ...]' go to 999 endif iarg=1 @@ -53,8 +53,8 @@ program fst280d if(arg(1:2).eq.'-h') then call getarg(iarg+1,arg) read(arg,*) hmod - if(hmod.ne.1.and.hmod.ne.2.and.hmod.ne.4) then - print*,'invalid modulation index. h must be 1, 2, or 4' + if(hmod.ne.1.and.hmod.ne.2.and.hmod.ne.4.and.hmod.ne.8) then + print*,'invalid modulation index. h must be 1, 2, 4, or 8' goto 999 endif iarg=iarg+2 @@ -84,25 +84,27 @@ program fst280d case('A') nsps=800 nmax=15*12000 - ndown=32/hmod + ndown=20/hmod + if(hmod.eq.8) ndown=2 case('B') nsps=1680 nmax=30*12000 - ndown=70/hmod - if(hmod.eq.4) ndown=15 + ndown=42/hmod ! 40 Sa/symbol + if(hmod.eq.4) ndown=10 + if(hmod.eq.8) ndown=5 case('C') nsps=4000 nmax=60*12000 - ndown=160/hmod + ndown=100/hmod ! 40 Sa/symbol + if(hmod.eq.8) ndown=16 case('D') nsps=8400 nmax=120*12000 - ndown=350/hmod - if(hmod.eq.4) ndown=84 + ndown=200/hmod case('E') nsps=21504 nmax=300*12000 - ndown=896/hmod + ndown=512/hmod end select nss=nsps/ndown fs=12000.0 !Sample rate @@ -122,12 +124,12 @@ program fst280d allocate( cframe(0:164*nss-1) ) allocate( iwave(nmax) ) -!write(*,*) 'nsps: ',nsps -!write(*,*) 'nmax: ',nmax -!write(*,*) 'nss : ',nss -!write(*,*) 'nspsec: ',fs2 -!write(*,*) 'nfft1 : ',nfft1 -!write(*,*) 'nfft2 : ',nfft2 +write(*,*) 'nsps: ',nsps +write(*,*) 'nmax: ',nmax +write(*,*) 'nss : ',nss +write(*,*) 'nspsec: ',fs2 +write(*,*) 'nfft1 : ',nfft1 +write(*,*) 'nfft2 : ',nfft2 ngood=0 ngoodsync=0 @@ -229,20 +231,19 @@ program fst280d fc2=fc21 isbest=isbest1 ntmax=4 - if(hmod .gt. 1.0) ntmax=1 + if(hmod .gt. 1) ntmax=1 ntmin=1 njitter=2 else fc2=fc28 isbest=isbest8 ntmax=4 - if(hmod .gt. 1.0) ntmax=1 + if(hmod .gt. 1) ntmax=1 ntmin=1 njitter=2 endif fc_synced = fc0 + fc2 dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 - call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) if(abs((isbest-fs2)/nss) .lt. 0.2 .and. abs(fc_synced-1500.0).lt.0.4) then @@ -251,8 +252,8 @@ program fst280d do ijitter=0,2 if(ijitter.eq.0) ioffset=0 - if(ijitter.eq.1) ioffset=2 - if(ijitter.eq.2) ioffset=-2 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 is0=isbest+ioffset if(is0.lt.0) cycle cframe=c2(is0:is0+164*nss-1) @@ -344,6 +345,7 @@ subroutine sync_fst280(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) complex z1,z2,z3 logical first integer isyncword(0:7) + integer hmod real f0save data isyncword/0,1,3,2,1,0,2,3/ data first/.true./ @@ -429,6 +431,7 @@ end subroutine fst280_downsample subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candidates) complex c_bigfft(0:nfft1/2) + integer hmod real candidates(100,3) real s(18000) real s2(18000) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index 72026344b..55c673854 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -12,6 +12,7 @@ program fst280sim complex, allocatable :: c0(:) complex, allocatable :: c(:) real, allocatable :: wave(:) + integer hmod integer itone(NN) integer*1 msgbits(101) integer*2, allocatable :: iwave(:) !Generated full-length waveform @@ -19,6 +20,7 @@ program fst280sim ! Get command-line argument(s) nargs=iargc() if(nargs.ne.9) then + print*,'Need 9 arguments, got ',nargs print*,'Usage: fst280sim "message" type f0 DT h fdop del nfiles snr' print*,'Examples: fst280sim "K1JT K9AN EN50" C 1500 0.0 1.0 0.1 1.0 10 -15' print*,'A: 15 sec' @@ -89,7 +91,7 @@ program fst280sim write(*,*) write(*,'(a9,a37)') 'Message: ',msgsent37 write(*,1000) f0,xdt,hmod,txt,snrdb -1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',f6.3,' TxT:',f6.1,' SNR:',f6.1) +1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) write(*,*) if(i3.eq.1) then write(*,*) ' mycall hiscall hisgrid' diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index dcf11ff4d..7905544ef 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -4,6 +4,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0,icmplx,cwave,wav complex cwave(nwave) real, allocatable, save :: pulse(:) real, allocatable :: dphi(:) + integer hmod integer itone(nsym) logical first data first/.true./ diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index a50088f66..639230fa7 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -10,6 +10,7 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) integer icos8(0:7) integer graymap(0:3) integer ip(1) + integer hmod logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits logical first logical badsync From 81c05489194a0b1926c8edd78029b62f72661b4b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 11:50:28 -0400 Subject: [PATCH 015/239] Add a dummy fst280 decoder. --- lib/decoder.f90 | 5 +++- lib/fst280_decode.f90 | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 lib/fst280_decode.f90 diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 61ff4163d..795444972 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -189,7 +189,10 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.280) then ! We're in FST280/FST280W mode - print*,'FST280/FST280W' + call timer('decfst28',0) + call my_fst280%decode(fst280_decoded,id2,params%nQSOProgress, & + params%nfqso,params%nfa,params%nfb,params%ndepth) + call timer('decfst28',1) go to 800 endif diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 new file mode 100644 index 000000000..2bdd86861 --- /dev/null +++ b/lib/fst280_decode.f90 @@ -0,0 +1,60 @@ +module fst280_decode + + type :: fst280_decoder + procedure(fst280_decode_callback), pointer :: callback + contains + procedure :: decode + end type fst280_decoder + + abstract interface + subroutine fst280_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual) + import fst280_decoder + implicit none + class(fst280_decoder), intent(inout) :: this + real, intent(in) :: sync + integer, intent(in) :: snr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + end subroutine fst280_decode_callback + end interface + +contains + + subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & + nfa,nfb,ndepth) + + use timer_module, only: timer + use packjt77 + include 'fst280/fst280_params.f90' + parameter (MAXCAND=100) + class(fst280_decoder), intent(inout) :: this + character*37 msg + character*120 data_dir + character*77 c77 + character*1 tr_designator + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real*8 fMHz + real llr(280),llra(280),llrb(280),llrc(280),llrd(280) + real candidates(100,3) + real bitmetrics(328,4) + integer ihdr(11) + integer*1 apmask(280),cw(280) + integer*1 hbits(328) + integer*1 message101(101),message74(74) + logical badsync,unpk77_success + integer*2 iwave(300*12000) + + write(*,3001) nQSOProgress,nfqso,nfa,nfb,ndepth +3001 format('aaa',5i5) + + + + end subroutine decode + +end module fst280_decode From 03632d97596304168b38e145ea7dc08a53af73ef Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 17 Jun 2020 11:24:29 -0500 Subject: [PATCH 016/239] Update sync thresholds and add threshold for h=8. --- lib/fst280/fst280d.f90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/fst280/fst280d.f90 b/lib/fst280/fst280d.f90 index dd683636d..45eff351d 100644 --- a/lib/fst280/fst280d.f90 +++ b/lib/fst280/fst280d.f90 @@ -89,13 +89,13 @@ program fst280d case('B') nsps=1680 nmax=30*12000 - ndown=42/hmod ! 40 Sa/symbol + ndown=42/hmod if(hmod.eq.4) ndown=10 if(hmod.eq.8) ndown=5 case('C') nsps=4000 nmax=60*12000 - ndown=100/hmod ! 40 Sa/symbol + ndown=100/hmod if(hmod.eq.8) ndown=16 case('D') nsps=8400 @@ -461,9 +461,10 @@ subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candida s2(i)=db(s2(i)) - 48.5 enddo - if(nh.eq.1) thresh=-29.5 - if(nh.eq.2) thresh=-27.0 - if(nh.eq.4) thresh=-25.0 + if(hmod.eq.1) thresh=-29.5 + if(hmod.eq.2) thresh=-27.0 + if(hmod.eq.4) thresh=-27.0 + if(hmod.eq.8) thresh=-27.0 ncand=0 do i=ia,ib From 5aeaf5dc7877ce771aeb4e9b129c5b3d3cbba580 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 14:17:03 -0400 Subject: [PATCH 017/239] Include h=8 and NSS=40 in the FST280 decoder. --- lib/decoder.f90 | 7 +- lib/fst280_decode.f90 | 426 ++++++++++++++++++++++++++++++++++++++--- widgets/mainwindow.cpp | 1 - 3 files changed, 402 insertions(+), 32 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 795444972..94fd367b2 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -189,10 +189,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.280) then ! We're in FST280/FST280W mode - call timer('decfst28',0) + call timer('dec280 ',0) + ntrperiod=params%kin/12000 call my_fst280%decode(fst280_decoded,id2,params%nQSOProgress, & - params%nfqso,params%nfa,params%nfb,params%ndepth) - call timer('decfst28',1) + params%nfqso,params%nfa,params%nfb,params%ndepth,ntrperiod) + call timer('dec280 ',1) go to 800 endif diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 2bdd86861..9a9958a9e 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -23,38 +23,408 @@ module fst280_decode contains - subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & - nfa,nfb,ndepth) + subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & + nfa,nfb,ndepth,ntrperiod) - use timer_module, only: timer - use packjt77 - include 'fst280/fst280_params.f90' - parameter (MAXCAND=100) - class(fst280_decoder), intent(inout) :: this - character*37 msg - character*120 data_dir - character*77 c77 - character*1 tr_designator - complex, allocatable :: c2(:) - complex, allocatable :: cframe(:) - complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable :: r_data(:) - real*8 fMHz - real llr(280),llra(280),llrb(280),llrc(280),llrd(280) - real candidates(100,3) - real bitmetrics(328,4) - integer ihdr(11) - integer*1 apmask(280),cw(280) - integer*1 hbits(328) - integer*1 message101(101),message74(74) - logical badsync,unpk77_success - integer*2 iwave(300*12000) + use timer_module, only: timer + use packjt77 + include 'fst280/fst280_params.f90' + parameter (MAXCAND=100) + class(fst280_decoder), intent(inout) :: this + character*37 msg + character*120 data_dir + character*77 c77 + character*1 tr_designator + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real*8 fMHz + real llr(280),llra(280),llrb(280),llrc(280),llrd(280) + real candidates(100,3) + real bitmetrics(328,4) + integer hmod,ihdr(11) + integer*1 apmask(280),cw(280) + integer*1 hbits(328) + integer*1 message101(101),message74(74) + logical badsync,unpk77_success + integer*2 iwave(300*12000) - write(*,3001) nQSOProgress,nfqso,nfa,nfb,ndepth -3001 format('aaa',5i5) + hmod=1 !### pass as arg ### + Keff=91 + ndeep=3 + iwspr=0 + nmax=15*12000 + if(ntrperiod.eq.15) then + nsps=800 + nmax=15*12000 + ndown=20/hmod + if(hmod.eq.8) ndown=2 + else if(ntrperiod.eq.30) then + nsps=1680 + nmax=30*12000 + ndown=42/hmod + if(hmod.eq.4) ndown=10 + if(hmod.eq.8) ndown=5 + else if(ntrperiod.eq.60) then + nsps=4000 + nmax=60*12000 + ndown=100/hmod + if(hmod.eq.8) ndown=16 + else if(ntrperiod.eq.120) then + nsps=8400 + nmax=120*12000 + ndown=200/hmod + else if(ntrperiod.eq.300) then + nsps=21504 + nmax=300*12000 + ndown=512/hmod + end if + nss=nsps/ndown + fs=12000.0 !Sample rate + fs2=fs/ndown + nspsec=nint(fs2) + dt=1.0/fs !Sample interval (s) + dt2=1.0/fs2 + tt=nsps*dt !Duration of "itone" symbols (s) + nfft1=2*int(nmax/2) + nh1=nfft1/2 + allocate( r_data(1:nfft1+2) ) + allocate( c_bigfft(0:nfft1/2) ) - end subroutine decode + nfft2=nfft1/ndown + allocate( c2(0:nfft2-1) ) + allocate( cframe(0:164*nss-1) ) + + ngood=0 + ngoodsync=0 + npts=nmax + fa=100.0 + fb=3500.0 + +! The big fft is done once and is used for calculating the smoothed spectrum +! and also for downconverting/downsampling each candidate. + r_data(1:nfft1)=iwave(1:nfft1) + r_data(nfft1+1:nfft1+2)=0.0 + call four2a(r_data,nfft1,1,-1,0) + c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + +! Get first approximation of candidate frequencies + call get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + ncand,candidates) + + ndecodes=0 + isbest1=0 + isbest8=0 + fc21=fc0 + fc28=fc0 + do icand=1,ncand + fc0=candidates(icand,1) + xsnr=candidates(icand,2) + +! Downconvert and downsample a slice of the spectrum centered on the +! rough estimate of the candidates frequency. +! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. +! The size of the downsampled c2 array is nfft2=nfft1/ndown + + call fst280_downsample(c_bigfft,nfft1,ndown,fc0,c2) + + call timer('sync280 ',0) + do isync=0,1 + if(isync.eq.0) then + fc1=0.0 + is0=nint(fs2) + ishw=is0 + isst=4 + ifhw=10 + df=.1*8400/nsps + else if(isync.eq.1) then + fc1=fc28 + is0=isbest8 + ishw=4 + isst=1 + ifhw=10 + df=.02*8400/nsps + endif + + smax1=0.0 + smax8=0.0 + do if=-ifhw,ifhw + fc=fc1+df*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst280(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) + call sync_fst280(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) + if(sync8.gt.smax8) then + fc28=fc + isbest8=istart + smax8=sync8 + endif + if(sync1.gt.smax1) then + fc21=fc + isbest1=istart + smax1=sync1 + endif + enddo + enddo + enddo + call timer('sync280 ',1) + + if(smax8/smax1 .lt. 0.65 ) then + fc2=fc21 + isbest=isbest1 + ntmax=4 + if(hmod.gt.1) ntmax=1 + ntmin=1 + njitter=2 + else + fc2=fc28 + isbest=isbest8 + ntmax=4 + if(hmod.gt.1) ntmax=1 + ntmin=1 + njitter=2 + endif + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + + call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) + + if(abs((isbest-fs2)/nss) .lt. 0.2 .and. abs(fc_synced-1500.0).lt.0.4) then + ngoodsync=ngoodsync+1 + endif + + do ijitter=0,2 + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+164*nss-1) + s2=sum(cframe*conjg(cframe)) + cframe=cframe/sqrt(s2) + call get_fst280_bitmetrics(cframe,nss,hmod,bitmetrics,badsync) + + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) + ns2=count(hbits( 9: 16).eq.(/0,1,0,0,1,1,1,0/)) + ns3=count(hbits(157:164).eq.(/0,0,0,1,1,0,1,1/)) + ns4=count(hbits(165:172).eq.(/0,1,0,0,1,1,1,0/)) + ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) + ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 +! if(nsync_qual.lt. 20) cycle + + scalefac=2.83 + llra( 1:140)=bitmetrics( 17:156, 1) + llra(141:280)=bitmetrics(173:312, 1) + llra=scalefac*llra + llrb( 1:140)=bitmetrics( 17:156, 2) + llrb(141:280)=bitmetrics(173:312, 2) + llrb=scalefac*llrb + llrc( 1:140)=bitmetrics( 17:156, 3) + llrc(141:280)=bitmetrics(173:312, 3) + llrc=scalefac*llrc + llrd( 1:140)=bitmetrics( 17:156, 4) + llrd(141:280)=bitmetrics(173:312, 4) + llrd=scalefac*llrd + apmask=0 + + do itry=ntmax,ntmin,-1 + if(itry.eq.1) llr=llra + if(itry.eq.2) llr=llrb + if(itry.eq.3) llr=llrc + if(itry.eq.4) llr=llrd + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iwspr.eq.0) then + maxosd=2 + call timer('d280_101',0) + call decode280_101(llr,Keff,maxosd,ndeep,apmask,message101, & + cw,ntype,nharderrors,dmin) + call timer('d280_101',1) + else + maxosd=2 + call timer('d280_74 ',0) + call decode280_74(llr,Keff,maxosd,ndeep,apmask,message74,cw, & + ntype,nharderrors,dmin) + call timer('d280_74 ',1) + endif + if(nharderrors .ge.0) then + if(iwspr.eq.0) then + write(c77,'(77i1)') message101(1:77) + call unpack77(c77,0,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,0,msg,unpk77_success) + endif + if(nharderrors .ge.0 .and. unpk77_success) then + ngood=ngood+1 + write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced),msg(1:22) +1100 format(i6.6,i5,f5.1,i5,' `',1x,a22) + goto 2002 + else + cycle + endif + endif + enddo ! metrics + enddo ! istart jitter +2002 continue + enddo !candidate list + write(*,1120) +1120 format("") + + return + end subroutine decode + + subroutine sync_fst280(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + +! Compute sync power for a complex, downsampled FST280 signal. + + include 'fst280/fst280_params.f90' + complex cd0(0:np-1) + complex, allocatable, save :: csync(:) + complex, allocatable, save :: csynct(:) + complex ctwk(8*nss) + complex z1,z2,z3 + logical first + integer hmod,isyncword(0:7) + real f0save + data isyncword/0,1,3,2,1,0,2,3/ + data first/.true./ + data f0save/0.0/ + save first,twopi,dt,fac,f0save + + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Statement function for power + + if( first ) then + allocate( csync(8*nss) ) + allocate( csynct(8*nss) ) + twopi=8.0*atan(1.0) + dt=1/fs + k=1 + phi=0.0 + do i=0,7 + dphi=twopi*hmod*(isyncword(i)-1.5)/real(nss) + do j=1,nss + csync(k)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + k=k+1 + enddo + enddo + first=.false. + fac=1.0/(8.0*nss) + endif + + if(f0.ne.f0save) then + dphi=twopi*f0*dt + phi=0.0 + do i=1,8*nss + ctwk(i)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + enddo + csynct=ctwk*csync + f0save=f0 + endif + + i1=i0 !Costas arrays + i2=i0+78*nss + i3=i0+156*nss + + s1=0.0 + s2=0.0 + s3=0.0 + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + enddo + + sync = s1+s2+s3 + + return + end subroutine sync_fst280 + + subroutine fst280_downsample(c_bigfft,nfft1,ndown,f0,c1) + +! Output: Complex data in c(), sampled at 12000/ndown Hz + + complex c_bigfft(0:nfft1/2) + complex c1(0:nfft1/ndown-1) + + df=12000.0/nfft1 + i0=nint(f0/df) + c1(0)=c_bigfft(i0) + nfft2=nfft1/ndown + do i=1,nfft2/2 + if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) + if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) + enddo + c1=c1/nfft2 + call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain + return + + end subroutine fst280_downsample + + subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + ncand,candidates) + + complex c_bigfft(0:nfft1/2) + integer hmod + real candidates(100,3) + real s(18000) + real s2(18000) + data nfft1z/-1/ + save nfft1z + + nh1=nfft1/2 + df1=fs/nfft1 + baud=fs/nsps + df2=baud/2.0 + nd=df1/df2 + ndh=nd/2 + ia=fa/df2 + ib=fb/df2 + s=0. + do i=ia,ib + j0=nint(i*df2/df1) + do j=j0-ndh,j0+ndh + s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + enddo + enddo + call pctile(s(ia:ib),ib-ia+1,30,base) + s=s/base + nh=hmod + do i=ia,ib + s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) + s2(i)=db(s2(i)) - 48.5 + enddo + + if(hmod.eq.1) thresh=-29.5 !### temporaray? ### + if(hmod.eq.2) thresh=-27.0 + if(hmid.eq.4) thresh=-25.0 + + ncand=0 + do i=ia,ib + if((s2(i).gt.s2(i-1)).and. & + (s2(i).gt.s2(i+1)).and. & + (s2(i).gt.thresh).and.ncand.lt.100) then + ncand=ncand+1 + candidates(ncand,1)=df2*i + candidates(ncand,2)=s2(i) + endif + enddo + + return + end subroutine get_candidates_fst280 end module fst280_decode diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 1b1b2a685..c56ccaaf5 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1393,7 +1393,6 @@ void MainWindow::dataSink(qint64 frames) if(m_mode=="MSK144") return; fixStop(); - qDebug() << "aa" << m_hsymStop << m_ihsym << m_TRperiod; if (m_mode == "FreqCal" // only calculate after 1st chunk, also skip chunk where rig // changed frequency From b0a979e3f2b86dd4c8168ac5550dcf14b445212b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 15:07:15 -0400 Subject: [PATCH 018/239] Enable FST280 decoding with jt9[.exe]. So far, with 60 s periods only. --- lib/jt9.f90 | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 7656f51e2..e2ced6542 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -25,7 +25,7 @@ program jt9 fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=1,nexp_decode=0 logical :: read_files = .true., tx9 = .false., display_help = .false., & bLowSidelobes = .false. - type (option) :: long_options(26) = [ & + type (option) :: long_options(27) = [ & option ('help', .false., 'h', 'Display this help message', ''), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & option ('tr-period', .true., 'p', 'Tx/Rx period, default MINUTES=1', & @@ -52,7 +52,8 @@ program jt9 'THREADS'), & option ('jt4', .false., '4', 'JT4 mode', ''), & option ('ft4', .false., '5', 'FT4 mode', ''), & - option ('jt65', .false.,'6', 'JT65 mode', ''), & + option ('jt65', .false.,'6', 'JT65 mode', ''), & + option ('fst280', .false., '7', 'FT8 mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & @@ -79,7 +80,7 @@ program jt9 nsubmode = 0 do - call getopt('hs:e:a:b:r:m:p:d:f:w:t:98654qTL:S:H:c:G:x:g:X:', & + call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654qTL:S:H:c:G:x:g:X:', & long_options,c,optarg,arglen,stat,offset,remain,.true.) if (stat .ne. 0) then exit @@ -120,10 +121,12 @@ program jt9 mode = 5 case ('6') if (mode.lt.65) mode = mode + 65 - case ('9') - if (mode.lt.9.or.mode.eq.65) mode = mode + 9 + case ('7') + mode = 280 case ('8') mode = 8 + case ('9') + if (mode.lt.9.or.mode.eq.65) mode = mode + 9 case ('T') tx9 = .true. case ('w') @@ -182,7 +185,6 @@ program jt9 allocate(shared_data) nflatten=0 - do iarg = offset + 1, offset + remain call get_command_argument (iarg, optarg, arglen) infile = optarg(:arglen) @@ -220,11 +222,11 @@ program jt9 k=0 nhsym0=-999 npts=(60*ntrperiod-6)*12000 + if(mode.eq.280) npts=60*ntrperiod*12000 if(iarg .eq. offset + 1) then call init_timer (trim(data_dir)//'/timer.out') call timer('jt9 ',0) endif - shared_data%id2=0 !??? Why is this necessary ??? if(mode.eq.5) npts=21*3456 do iblk=1,npts/kstep @@ -249,7 +251,7 @@ program jt9 call timer('symspec ',1) endif nhsym0=nhsym - if(nhsym.ge.181) exit + if(nhsym.ge.181 .and. mode.ne.280) exit endif enddo close(unit=wav%lun) @@ -264,20 +266,14 @@ program jt9 shared_data%params%nfb=fhigh shared_data%params%ntol=20 shared_data%params%kin=64800 + if(mode.eq.280) shared_data%params%kin=720000 !### 60 s periods ### shared_data%params%nzhsym=181 shared_data%params%ndepth=ndepth shared_data%params%lft8apon=.true. shared_data%params%ljt65apon=.true. shared_data%params%napwid=75 shared_data%params%dttol=3. - -! shared_data%params%minsync=0 !### TEST ONLY -! shared_data%params%nfqso=1500 !### TEST ONLY -! mycall="G3WDG " !### TEST ONLY -! hiscall="VK7MO " !### TEST ONLY -! hisgrid="QE37 " !### TEST ONLY if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100 - shared_data%params%naggressive=0 shared_data%params%n2pass=2 ! shared_data%params%nranera=8 !### ntrials=10000 From 1cebbd2cdde79b8c01e3571ced623188fd78f8df Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 19:28:44 -0400 Subject: [PATCH 019/239] Enable decoding of FST280 for other T/R sequence lengths. Needs testing! --- lib/jt9.f90 | 35 ++++++++++++++--------------------- lib/symspec.f90 | 7 ++++--- widgets/mainwindow.cpp | 5 ++--- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index e2ced6542..3c5a3f9c2 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -17,19 +17,20 @@ program jt9 integer(C_INT) iret type(wav_header) wav real*4 s(NSMAX) + real*8 TRperiod character c character(len=500) optarg, infile character wisfile*80 !### ndepth was defined as 60001. Why??? integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, & - fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=1,nexp_decode=0 + fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0 logical :: read_files = .true., tx9 = .false., display_help = .false., & bLowSidelobes = .false. type (option) :: long_options(27) = [ & option ('help', .false., 'h', 'Display this help message', ''), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & - option ('tr-period', .true., 'p', 'Tx/Rx period, default MINUTES=1', & - 'MINUTES'), & + option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', & + 'SECONDS'), & option ('executable-path', .true., 'e', & 'Location of subordinate executables (KVASD) default PATH="."', & 'PATH'), & @@ -78,6 +79,7 @@ program jt9 data npatience/1/,nthreads/1/ nsubmode = 0 + TRperiod=60.d0 do call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654qTL:S:H:c:G:x:g:X:', & @@ -102,7 +104,7 @@ program jt9 case ('m') read (optarg(:arglen), *) nthreads case ('p') - read (optarg(:arglen), *) ntrperiod + read (optarg(:arglen), *) TRperiod case ('d') read (optarg(:arglen), *) ndepth case ('f') @@ -200,29 +202,20 @@ program jt9 go to 2 1 nutc=0 2 nsps=0 - if(ntrperiod.eq.1) then + if(TRperiod.eq.60.d0) then nsps=6912 shared_data%params%nzhsym=181 - else if(ntrperiod.eq.2) then - nsps=15360 - shared_data%params%nzhsym=178 - else if(ntrperiod.eq.5) then - nsps=40960 - shared_data%params%nzhsym=172 - else if(ntrperiod.eq.10) then - nsps=82944 - shared_data%params%nzhsym=171 - else if(ntrperiod.eq.30) then - nsps=252000 - shared_data%params%nzhsym=167 + endif + if(mode.eq.280) then + nsps=6912 + npts=TRperiod*12000.d0 endif if(nsps.eq.0) stop 'Error: bad TRperiod' kstep=nsps/2 k=0 nhsym0=-999 - npts=(60*ntrperiod-6)*12000 - if(mode.eq.280) npts=60*ntrperiod*12000 + npts=(TRperiod-6.d0)*12000.d0 if(iarg .eq. offset + 1) then call init_timer (trim(data_dir)//'/timer.out') call timer('jt9 ',0) @@ -246,8 +239,8 @@ program jt9 ingain=0 call timer('symspec ',0) nminw=1 - call symspec(shared_data,k,ntrperiod,nsps,ingain,bLowSidelobes,nminw,pxdb, & - s,df3,ihsym,npts8,pxdbmax) + call symspec(shared_data,k,Tperiod,nsps,ingain, & + bLowSidelobes,nminw,pxdb,s,df3,ihsym,npts8,pxdbmax) call timer('symspec ',1) endif nhsym0=nhsym diff --git a/lib/symspec.f90 b/lib/symspec.f90 index b9f5e2088..f97757778 100644 --- a/lib/symspec.f90 +++ b/lib/symspec.f90 @@ -1,9 +1,9 @@ -subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,bLowSidelobes, & +subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & nminw,pxdb,s,df3,ihsym,npts8,pxdbmax) ! Input: ! k pointer to the most recent new data -! ntrperiod T/R sequence length, minutes +! TRperiod T/R sequence length, seconds ! nsps samples per symbol, at 12000 Hz ! bLowSidelobes true to use windowed FFTs ! ndiskdat 0/1 to indicate if data from disk @@ -23,6 +23,7 @@ subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,bLowSidelobes, & include 'jt9com.f90' type(dec_data) :: shared_data + real*8 TRperiod real*4 w3(MAXFFT3) real*4 s(NSMAX) real*4 ssum(NSMAX) @@ -38,7 +39,7 @@ subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,bLowSidelobes, & equivalence (xc,cx) save - if(ntrperiod.eq.-999) stop !Silence compiler warning + if(TRperiod.lt.0.d0) stop !Silence compiler warning nfft3=16384 !df=12000.0/16384 = 0.732422 jstep=nsps/2 !Step size = half-symbol in id2() if(k.gt.NMAX) go to 900 diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index c56ccaaf5..4fdc12850 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -89,7 +89,7 @@ extern "C" { //----------------------------------------------------- C and Fortran routines - void symspec_(struct dec_data *, int* k, int* ntrperiod, int* nsps, int* ingain, + void symspec_(struct dec_data *, int* k, double* trperiod, int* nsps, int* ingain, bool* bLowSidelobes, int* minw, float* px, float s[], float* df3, int* nhsym, int* npts8, float *m_pxmax); @@ -1373,14 +1373,13 @@ void MainWindow::dataSink(qint64 frames) } // Get power, spectrum, and ihsym - int trmin=m_TRperiod/60.0; dec_data.params.nfa=m_wideGraph->nStartFreq(); dec_data.params.nfb=m_wideGraph->Fmax(); int nsps=m_nsps; if(m_bFastMode) nsps=6912; int nsmo=m_wideGraph->smoothYellow()-1; bool bLowSidelobes=m_config.lowSidelobes(); - symspec_(&dec_data,&k,&trmin,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, + symspec_(&dec_data,&k,&m_TRperiod,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, &m_df3,&m_ihsym,&m_npts8,&m_pxmax); if(m_mode=="WSPR") wspr_downsample_(dec_data.d2,&k); if(m_ihsym <=0) return; From 5c3a340f72b1528ed0d89f99771c60e81191436b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 19:58:21 -0400 Subject: [PATCH 020/239] Pass TRperiod (s) to fst280_decode(). --- lib/decoder.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 94fd367b2..b79e77ccd 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -190,9 +190,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.280) then ! We're in FST280/FST280W mode call timer('dec280 ',0) - ntrperiod=params%kin/12000 call my_fst280%decode(fst280_decoded,id2,params%nQSOProgress, & - params%nfqso,params%nfa,params%nfb,params%ndepth,ntrperiod) + params%nfqso,params%nfa,params%nfb,params%ndepth,params%ntr) call timer('dec280 ',1) go to 800 endif From 07721761a9de68426256e150f0b8ba6e727bf116 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 17 Jun 2020 20:31:54 -0400 Subject: [PATCH 021/239] Fix a few more passings of parameters from jt9 to decoder, for FST280. --- lib/fst280_decode.f90 | 2 +- lib/jt9.f90 | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 9a9958a9e..bfbbded60 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -49,7 +49,7 @@ contains integer*1 message101(101),message74(74) logical badsync,unpk77_success integer*2 iwave(300*12000) - + hmod=1 !### pass as arg ### Keff=91 ndeep=3 diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 3c5a3f9c2..49bfbea2a 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -202,20 +202,18 @@ program jt9 go to 2 1 nutc=0 2 nsps=0 + npts=TRperiod*12000.d0 if(TRperiod.eq.60.d0) then nsps=6912 shared_data%params%nzhsym=181 + npts=(TRperiod-6.d0)*12000.d0 endif - if(mode.eq.280) then - nsps=6912 - npts=TRperiod*12000.d0 - endif + if(mode.eq.280) nsps=6912 if(nsps.eq.0) stop 'Error: bad TRperiod' - + kstep=nsps/2 k=0 nhsym0=-999 - npts=(TRperiod-6.d0)*12000.d0 if(iarg .eq. offset + 1) then call init_timer (trim(data_dir)//'/timer.out') call timer('jt9 ',0) @@ -250,7 +248,7 @@ program jt9 close(unit=wav%lun) shared_data%params%nutc=nutc shared_data%params%ndiskdat=.true. - shared_data%params%ntr=60 + shared_data%params%ntr=TRperiod shared_data%params%nfqso=nrxfreq shared_data%params%newdat=.true. shared_data%params%npts8=74736 From 3172f1e97685a94e9e8d739d45e5bb07eddee472 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 18 Jun 2020 08:14:11 -0500 Subject: [PATCH 022/239] Fix a type, add threshold for h=8, tweak gen_candidates to decrease the number of spurious candidates. --- lib/fst280_decode.f90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index bfbbded60..326e81f2d 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -408,15 +408,19 @@ contains s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) s2(i)=db(s2(i)) - 48.5 enddo + if(hmod.eq.1) thresh=-29.5 !### temporaray? ### if(hmod.eq.2) thresh=-27.0 - if(hmid.eq.4) thresh=-25.0 + if(hmod.eq.4) thresh=-27.0 + if(hmod.eq.8) thresh=-27.0 ncand=0 + if(ia.lt.3) ia=3 + if(ib.gt.18000-2) ib=18000-2 do i=ia,ib - if((s2(i).gt.s2(i-1)).and. & - (s2(i).gt.s2(i+1)).and. & + if((s2(i).gt.s2(i-2)).and. & + (s2(i).gt.s2(i+2)).and. & (s2(i).gt.thresh).and.ncand.lt.100) then ncand=ncand+1 candidates(ncand,1)=df2*i From 54c1df030b2f5bdf75281fbe263b19531d29ad98 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 18 Jun 2020 11:25:32 -0400 Subject: [PATCH 023/239] Fix the logic for setting length of FST280 data sent from jt9 to decoder. --- lib/jt9.f90 | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 49bfbea2a..afd5c374e 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -201,18 +201,11 @@ program jt9 endif go to 2 1 nutc=0 -2 nsps=0 +2 nsps=6912 npts=TRperiod*12000.d0 - if(TRperiod.eq.60.d0) then - nsps=6912 - shared_data%params%nzhsym=181 - npts=(TRperiod-6.d0)*12000.d0 - endif - if(mode.eq.280) nsps=6912 - if(nsps.eq.0) stop 'Error: bad TRperiod' - kstep=nsps/2 k=0 + nhsym=0 nhsym0=-999 if(iarg .eq. offset + 1) then call init_timer (trim(data_dir)//'/timer.out') @@ -258,7 +251,7 @@ program jt9 shared_data%params%ntol=20 shared_data%params%kin=64800 if(mode.eq.280) shared_data%params%kin=720000 !### 60 s periods ### - shared_data%params%nzhsym=181 + shared_data%params%nzhsym=nhsym shared_data%params%ndepth=ndepth shared_data%params%lft8apon=.true. shared_data%params%ljt65apon=.true. @@ -321,11 +314,6 @@ program jt9 999 continue ! Output decoder statistics call fini_timer () -! open (unit=12, file=trim(data_dir)//'/timer.out', status='unknown', position='append') -! write(12,1100) n65a,ntry65a,n65b,ntry65b,numfano,num9 -!1100 format(58('-')/' JT65_1 Tries_1 JT65_2 Tries_2 JT9 Tries'/ & -! 58('-')/6i8) - ! Save wisdom and free memory iret=fftwf_export_wisdom_to_filename(wisfile) call four2a(a,-1,1,1,1) From 72005888ac835586105853627e562204a9409b45 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 18 Jun 2020 13:37:49 -0400 Subject: [PATCH 024/239] Starting to implement callback routine fst280_decoded. Not yet functional! --- lib/decoder.f90 | 42 +++++++++++++++++++++++++++++++++++++++++- lib/fst280_decode.f90 | 8 +++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index b79e77ccd..c2247d6d0 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -315,7 +315,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ! JT65 is not yet producing info for nsynced, ndecoded. 800 ndecoded = my_jt4%decoded + my_jt65%decoded + my_jt9%decoded + & - my_ft8%decoded + my_ft4%decoded + my_ft8%decoded + my_ft4%decoded + my_fst280%decoded if(params%nmode.eq.8 .and. params%nzhsym.eq.41) ndec41=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.47) ndec47=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.50) then @@ -676,4 +676,44 @@ contains return end subroutine ft4_decoded + +! subroutine fst280_decoded (this,sync,nsnr,dt,freq,decoded,nap,qual) + +! use fst280_decode +! implicit none + +! class(fst280_decoder), intent(inout) :: this +! real, intent(in) :: sync +! integer, intent(in) :: nsnr +! real, intent(in) :: dt +! real, intent(in) :: freq +! character(len=37), intent(in) :: decoded +! integer, intent(in) :: nap +! real, intent(in) :: qual +! character*2 annot +! character*37 decoded0 + +! decoded0=decoded +! annot=' ' +! if(nap.ne.0) then +! write(annot,'(a1,i1)') 'a',nap +! if(qual.lt.0.17) decoded0(37:37)='?' +! endif + +! write(*,1001) params%nutc,nsnr,dt,nint(freq),decoded0,annot +!1001 format(i6.6,i4,f5.1,i5,' + ',1x,a37,1x,a2) +! write(13,1002) params%nutc,nint(sync),nsnr,dt,freq,0,decoded0 +!1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') + +! call flush(6) +! call flush(13) + +! select type(this) +! type is (counting_fst280_decoder) +! this%decoded = this%decoded + 1 +! end select + +! return +! end subroutine fst280_decoded + end subroutine multimode_decoder diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 326e81f2d..bc4247efd 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -264,8 +264,14 @@ contains endif if(nharderrors .ge.0 .and. unpk77_success) then ngood=ngood+1 - write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced),msg(1:22) + write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced), & + msg(1:22) 1100 format(i6.6,i5,f5.1,i5,' `',1x,a22) + +! nsnr=nint(xsnr) +! iaptype=0 +! qual=0. +! call this%callback(smax1,nsnr,xdt,fc_synced,msg,iaptype,qual) goto 2002 else cycle From b270e7372f5e1fae74e71abbb2ebe38d03fd5d01 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 18 Jun 2020 15:03:41 -0400 Subject: [PATCH 025/239] Use hhmm in file name if TRperiod.ge.60. --- lib/fst280/fst280sim.f90 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index c5f4fba12..577589beb 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -137,9 +137,14 @@ program fst280sim if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." iwave=nint(wave) h=default_header(12000,nmax) - write(fname,1102) ifile -1102 format('000000_',i6.6,'.wav') - open(10,file=fname,status='unknown',access='stream') + if(nmax/12000.le.30) then + write(fname,1102) ifile +1102 format('000000_',i6.6,'.wav') + else + write(fname,1104) ifile +1104 format('000000_',i4.4,'.wav') + endif + open(10,file=trim(fname),status='unknown',access='stream') write(10) h,iwave !Save to *.wav file close(10) write(*,1110) ifile,xdt,f0,snrdb,fname From 402ce1b3fb08b9fd724a12f659e38995fdcef9bb Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 18 Jun 2020 23:33:36 +0100 Subject: [PATCH 026/239] Enable passing decodes back to caller --- lib/decoder.f90 | 62 ++++++++++++++++++++-------------------- lib/fst280/fst280sim.f90 | 2 +- lib/fst280_decode.f90 | 18 ++++++------ 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index c2247d6d0..e4b6b3a80 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -677,43 +677,43 @@ contains return end subroutine ft4_decoded -! subroutine fst280_decoded (this,sync,nsnr,dt,freq,decoded,nap,qual) + subroutine fst280_decoded (this,sync,nsnr,dt,freq,decoded,nap,qual) -! use fst280_decode -! implicit none + use fst280_decode + implicit none -! class(fst280_decoder), intent(inout) :: this -! real, intent(in) :: sync -! integer, intent(in) :: nsnr -! real, intent(in) :: dt -! real, intent(in) :: freq -! character(len=37), intent(in) :: decoded -! integer, intent(in) :: nap -! real, intent(in) :: qual -! character*2 annot -! character*37 decoded0 + class(fst280_decoder), intent(inout) :: this + real, intent(in) :: sync + integer, intent(in) :: nsnr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + character*2 annot + character*37 decoded0 -! decoded0=decoded -! annot=' ' -! if(nap.ne.0) then -! write(annot,'(a1,i1)') 'a',nap -! if(qual.lt.0.17) decoded0(37:37)='?' -! endif + decoded0=decoded + annot=' ' + if(nap.ne.0) then + write(annot,'(a1,i1)') 'a',nap + if(qual.lt.0.17) decoded0(37:37)='?' + endif -! write(*,1001) params%nutc,nsnr,dt,nint(freq),decoded0,annot -!1001 format(i6.6,i4,f5.1,i5,' + ',1x,a37,1x,a2) -! write(13,1002) params%nutc,nint(sync),nsnr,dt,freq,0,decoded0 -!1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') + write(*,1001) params%nutc,nsnr,dt,nint(freq),decoded0,annot +1001 format(i6.6,i4,f5.1,i5,' + ',1x,a37,1x,a2) + write(13,1002) params%nutc,nint(sync),nsnr,dt,freq,0,decoded0 +1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') -! call flush(6) -! call flush(13) + call flush(6) + call flush(13) -! select type(this) -! type is (counting_fst280_decoder) -! this%decoded = this%decoded + 1 -! end select + select type(this) + type is (counting_fst280_decoder) + this%decoded = this%decoded + 1 + end select -! return -! end subroutine fst280_decoded + return + end subroutine fst280_decoded end subroutine multimode_decoder diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index c5f4fba12..53c887271 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -22,7 +22,7 @@ program fst280sim if(nargs.ne.9) then print*,'Need 9 arguments, got ',nargs print*,'Usage: fst280sim "message" type f0 DT h fdop del nfiles snr' - print*,'Examples: fst280sim "K1JT K9AN EN50" C 1500 0.0 1.0 0.1 1.0 10 -15' + print*,'Examples: fst280sim "K1JT K9AN EN50" C 1500 0.0 1 0.1 1.0 10 -15' print*,'A: 15 sec' print*,'B: 30 sec' print*,'C: 1 min' diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index bc4247efd..265c72615 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -31,6 +31,7 @@ contains include 'fst280/fst280_params.f90' parameter (MAXCAND=100) class(fst280_decoder), intent(inout) :: this + procedure(fst280_decode_callback) :: callback character*37 msg character*120 data_dir character*77 c77 @@ -49,7 +50,8 @@ contains integer*1 message101(101),message74(74) logical badsync,unpk77_success integer*2 iwave(300*12000) - + + this%callback => callback hmod=1 !### pass as arg ### Keff=91 ndeep=3 @@ -264,14 +266,14 @@ contains endif if(nharderrors .ge.0 .and. unpk77_success) then ngood=ngood+1 - write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced), & - msg(1:22) -1100 format(i6.6,i5,f5.1,i5,' `',1x,a22) +! write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced), & +! msg(1:22) +! 1100 format(i6.6,i5,f5.1,i5,' `',1x,a22) -! nsnr=nint(xsnr) -! iaptype=0 -! qual=0. -! call this%callback(smax1,nsnr,xdt,fc_synced,msg,iaptype,qual) + nsnr=nint(xsnr) + iaptype=0 + qual=0. + call this%callback(smax1,nsnr,xdt,fc_synced,msg,iaptype,qual) goto 2002 else cycle From 55697009800fffcae8df27d511da10b136a631a0 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 18 Jun 2020 19:53:49 -0400 Subject: [PATCH 027/239] Send nutc to the fst280 decoder, and use it. Also some code cleanup. --- lib/decoder.f90 | 14 ++++++++------ lib/fst280_decode.f90 | 40 ++++++++++++++-------------------------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index e4b6b3a80..bc1b820ec 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -190,8 +190,9 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.280) then ! We're in FST280/FST280W mode call timer('dec280 ',0) - call my_fst280%decode(fst280_decoded,id2,params%nQSOProgress, & - params%nfqso,params%nfa,params%nfb,params%ndepth,params%ntr) + call my_fst280%decode(fst280_decoded,id2,params%nutc, & + params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & + params%ndepth,params%ntr) call timer('dec280 ',1) go to 800 endif @@ -677,12 +678,13 @@ contains return end subroutine ft4_decoded - subroutine fst280_decoded (this,sync,nsnr,dt,freq,decoded,nap,qual) + subroutine fst280_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap,qual) use fst280_decode implicit none class(fst280_decoder), intent(inout) :: this + integer, intent(in) :: nutc real, intent(in) :: sync integer, intent(in) :: nsnr real, intent(in) :: dt @@ -700,9 +702,9 @@ contains if(qual.lt.0.17) decoded0(37:37)='?' endif - write(*,1001) params%nutc,nsnr,dt,nint(freq),decoded0,annot -1001 format(i6.6,i4,f5.1,i5,' + ',1x,a37,1x,a2) - write(13,1002) params%nutc,nint(sync),nsnr,dt,freq,0,decoded0 + write(*,1001) nutc,nsnr,dt,nint(freq),decoded0,annot +1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) + write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') call flush(6) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 265c72615..ea9fd0020 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -7,12 +7,14 @@ module fst280_decode end type fst280_decoder abstract interface - subroutine fst280_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual) + subroutine fst280_decode_callback (this,nutc,sync,nsnr,dt,freq, & + decoded,nap,qual) import fst280_decoder implicit none class(fst280_decoder), intent(inout) :: this + integer, intent(in) :: nutc real, intent(in) :: sync - integer, intent(in) :: snr + integer, intent(in) :: nsnr real, intent(in) :: dt real, intent(in) :: freq character(len=37), intent(in) :: decoded @@ -23,8 +25,8 @@ module fst280_decode contains - subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & - nfa,nfb,ndepth,ntrperiod) + subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & + nfa,nfb,ndeep,ntrperiod) use timer_module, only: timer use packjt77 @@ -33,18 +35,15 @@ contains class(fst280_decoder), intent(inout) :: this procedure(fst280_decode_callback) :: callback character*37 msg - character*120 data_dir character*77 c77 - character*1 tr_designator complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform real, allocatable :: r_data(:) - real*8 fMHz real llr(280),llra(280),llrb(280),llrc(280),llrd(280) real candidates(100,3) real bitmetrics(328,4) - integer hmod,ihdr(11) + integer hmod integer*1 apmask(280),cw(280) integer*1 hbits(328) integer*1 message101(101),message74(74) @@ -53,8 +52,8 @@ contains this%callback => callback hmod=1 !### pass as arg ### + if(nfqso+nqsoprogress.eq.-999) return Keff=91 - ndeep=3 iwspr=0 nmax=15*12000 @@ -100,11 +99,9 @@ contains allocate( c2(0:nfft2-1) ) allocate( cframe(0:164*nss-1) ) - ngood=0 - ngoodsync=0 npts=nmax - fa=100.0 - fb=3500.0 + fa=nfa + fb=nfb ! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. @@ -120,8 +117,8 @@ contains ndecodes=0 isbest1=0 isbest8=0 - fc21=fc0 - fc28=fc0 + fc21=0. + fc28=0. do icand=1,ncand fc0=candidates(icand,1) xsnr=candidates(icand,2) @@ -192,10 +189,6 @@ contains dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) - - if(abs((isbest-fs2)/nss) .lt. 0.2 .and. abs(fc_synced-1500.0).lt.0.4) then - ngoodsync=ngoodsync+1 - endif do ijitter=0,2 if(ijitter.eq.0) ioffset=0 @@ -265,15 +258,11 @@ contains call unpack77(c77,0,msg,unpk77_success) endif if(nharderrors .ge.0 .and. unpk77_success) then - ngood=ngood+1 -! write(*,1100) 0,nint(xsnr),dt_synced,nint(fc_synced), & -! msg(1:22) -! 1100 format(i6.6,i5,f5.1,i5,' `',1x,a22) - nsnr=nint(xsnr) iaptype=0 qual=0. - call this%callback(smax1,nsnr,xdt,fc_synced,msg,iaptype,qual) + call this%callback(nutc,smax1,nsnr,xdt,fc_synced,msg, & + iaptype,qual) goto 2002 else cycle @@ -416,7 +405,6 @@ contains s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) s2(i)=db(s2(i)) - 48.5 enddo - if(hmod.eq.1) thresh=-29.5 !### temporaray? ### if(hmod.eq.2) thresh=-27.0 From d64e266e8ff93465cdb9d47e4b10a396907d83c2 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 09:15:00 -0400 Subject: [PATCH 028/239] Pass submode (==> hmod) to fst280_decode.f90. --- lib/decoder.f90 | 2 +- lib/fst280_decode.f90 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index bc1b820ec..c737a2ca6 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -192,7 +192,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) call timer('dec280 ',0) call my_fst280%decode(fst280_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & - params%ndepth,params%ntr) + params%nsubmode,params%ndepth,params%ntr) call timer('dec280 ',1) go to 800 endif diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index ea9fd0020..24d100589 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -26,7 +26,7 @@ module fst280_decode contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & - nfa,nfb,ndeep,ntrperiod) + nfa,nfb,nsubmode,ndeep,ntrperiod) use timer_module, only: timer use packjt77 @@ -51,12 +51,12 @@ contains integer*2 iwave(300*12000) this%callback => callback - hmod=1 !### pass as arg ### + hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return Keff=91 iwspr=0 - nmax=15*12000 + if(ntrperiod.eq.15) then nsps=800 nmax=15*12000 From 8933e43fb337a456a4e5786363c1123b1aee3db8 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 09:28:55 -0400 Subject: [PATCH 029/239] Use 15 30 60 120 300 rather than A B C D E for sequence length in FST280sim. --- lib/fst280/fst280sim.f90 | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index 8aa8e61fd..9d95279f5 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -8,7 +8,6 @@ program fst280sim type(hdr) h !Header for .wav file character arg*12,fname*17 character msg37*37,msgsent37*37,c77*77 - character tr_designator*1 complex, allocatable :: c0(:) complex, allocatable :: c(:) real, allocatable :: wave(:) @@ -21,18 +20,13 @@ program fst280sim nargs=iargc() if(nargs.ne.9) then print*,'Need 9 arguments, got ',nargs - print*,'Usage: fst280sim "message" type f0 DT h fdop del nfiles snr' - print*,'Examples: fst280sim "K1JT K9AN EN50" C 1500 0.0 1 0.1 1.0 10 -15' - print*,'A: 15 sec' - print*,'B: 30 sec' - print*,'C: 1 min' - print*,'D: 2 min' - print*,'E: 5 min' + print*,'Usage: fst280sim "message" TRsec f0 DT h fdop del nfiles snr' + print*,'Examples: fst280sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15' go to 999 endif call getarg(1,msg37) !Message to be transmitted call getarg(2,arg) - read(arg,*) tr_designator !TR selector + read(arg,*) nsec !TR sequence length, seconds call getarg(3,arg) read(arg,*) f0 !Frequency (only used for single-signal) call getarg(4,arg) @@ -53,23 +47,17 @@ program fst280sim fs=12000.0 !Sample rate (Hz) dt=1.0/fs !Sample interval (s) baud=1.0/tt !Keying rate (baud) - select case (tr_designator) - case('A') - nsps=800 - nmax=15*12000 - case('B') - nsps=1680 - nmax=30*12000 - case('C') - nsps=4000 - nmax=60*12000 - case('D') - nsps=8400 - nmax=120*12000 - case('E') - nsps=21504 - nmax=300*12000 - end select + nsps=0 + if(nsec.eq.15) nsps=800 + if(nsec.eq.30) nsps=1680 + if(nsec.eq.60) nsps=4000 + if(nsec.eq.120) nsps=8400 + if(nsec.eq.300) nsps=21504 + if(nsps.eq.0) then + print*,'Invalid TR sequence length.' + go to 999 + endif + nmax=nsec*12000 nz=nsps*NN nz2=nsps*NN2 txt=nz2*dt !Transmission length (s) From a4e32807d95966f004a0d9cf3d89bb9121d8994c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 09:59:12 -0400 Subject: [PATCH 030/239] Correct WSJT-X's display of UTC in FST280 decodes for TR < 60 s. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 4fdc12850..78eeae69a 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -2874,7 +2874,7 @@ void MainWindow::decode() //decode() m_msec0=QDateTime::currentMSecsSinceEpoch(); if(!m_dataAvailable or m_TRperiod==0.0) return; ui->DecodeButton->setChecked (true); - if(!dec_data.params.nagain && m_diskData && !m_bFastMode && m_mode!="FT8" && m_mode!="FT4") { + if(!dec_data.params.nagain && m_diskData && (m_TRperiod >= 60.0)) { dec_data.params.nutc=dec_data.params.nutc/100; } if(dec_data.params.nagain==0 && dec_data.params.newdat==1 && (!m_diskData)) { From 297c1a0dcbf30c3e62916135fc893c50f26fc315 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 10:16:04 -0400 Subject: [PATCH 031/239] Must reallocate some arrays when FST280 submode changes. --- lib/fst280/get_fst280_bitmetrics.f90 | 7 ++++--- lib/fst280_decode.f90 | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index b266fce82..50568210f 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -19,10 +19,11 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) real s4(0:3,NN) data icos8/0,1,3,2,1,0,2,3/ data graymap/0,1,3,2/ - data first/.true./ - save first,one,cp + data first/.true./,nss0/-1/ + save first,one,cp,nss0 - if(first) then + if(nss.ne.nss0 .and. allocated(c1)) deallocate(c1) + if(first .or. nss.ne.nss0) then allocate(c1(nss,0:3)) one=.false. do i=0,65535 diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 24d100589..e47e251e5 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -292,13 +292,12 @@ contains integer hmod,isyncword(0:7) real f0save data isyncword/0,1,3,2,1,0,2,3/ - data first/.true./ - data f0save/0.0/ - save first,twopi,dt,fac,f0save + data first/.true./,f0save/0.0/,nss0/-1/ + save first,twopi,dt,fac,f0save,nss0 + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power - p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Statement function for power - - if( first ) then + if(nss.ne.nss0 .and. allocated(csync)) deallocate(csync,csynct) + if(first .or. nss.ne.nss0) then allocate( csync(8*nss) ) allocate( csynct(8*nss) ) twopi=8.0*atan(1.0) @@ -314,6 +313,7 @@ contains enddo enddo first=.false. + nss0=nss fac=1.0/(8.0*nss) endif From acd04cc05028283845d19e885296ffd14c5668ec Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 11:43:34 -0400 Subject: [PATCH 032/239] Correctly restore FST280 submode on program restart. --- widgets/mainwindow.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 78eeae69a..f6dce34af 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4703,7 +4703,6 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie m_QSOProgress=ROGER_REPORT; } m_xRcvd=t[n-2] + " " + t[n-1]; -// qDebug() << "bb" << w2 << w34 << t0 << m_xRcvd; } else if(SpecOp::FIELD_DAY==m_config.special_op_id() and bFieldDay_msg) { if(t0=="R") { gen_msg=setTxMsg(4); @@ -5789,19 +5788,22 @@ void MainWindow::displayWidgets(qint64 n) void MainWindow::on_actionFST280_triggered() { + int nsub=m_nSubMode; on_actionJT65_triggered(); + ui->sbSubmode->setMaximum(3); + m_nSubMode=nsub; + ui->sbSubmode->setValue(m_nSubMode); m_mode="FST280"; m_modeTx="FST280"; ui->actionFST280->setChecked(true); WSPR_config(false); + bool bVHF=m_config.enable_VHF_features(); // 012345678901234567890123456789012 displayWidgets(nWidgets("111011000000111100010000000000000")); - bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); m_TRperiod = ui->sbTR->value (); ui->sbTR->setMinimum(15); ui->sbTR->setMaximum(300); - ui->sbSubmode->setMaximum(3); on_sbTR_valueChanged(ui->sbTR->value()); statusChanged(); } @@ -9002,8 +9004,6 @@ void MainWindow::set_mode (QString const& mode) else if ("ISCAT" == mode) on_actionISCAT_triggered (); else if ("MSK144" == mode) on_actionMSK144_triggered (); else if ("WSPR" == mode) on_actionWSPR_triggered (); - else if ("FST280" == mode) on_actionFST280_triggered (); - else if ("FST280W" == mode) on_actionFST280W_triggered (); else if ("Echo" == mode) on_actionEcho_triggered (); } From b2ae563a7d2bbc20cb3a93529f897222f862b420 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 11:57:49 -0400 Subject: [PATCH 033/239] For the user, define FST280 frequency as that of the lowest tone. --- lib/fst280/fst280sim.f90 | 9 +++++---- lib/fst280_decode.f90 | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index 9d95279f5..7c29d4298 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -28,7 +28,7 @@ program fst280sim call getarg(2,arg) read(arg,*) nsec !TR sequence length, seconds call getarg(3,arg) - read(arg,*) f0 !Frequency (only used for single-signal) + read(arg,*) f00 !Frequency (only used for single-signal) call getarg(4,arg) read(arg,*) xdt !Time offset from nominal (s) call getarg(5,arg) @@ -46,7 +46,6 @@ program fst280sim twopi=8.0*atan(1.0) fs=12000.0 !Sample rate (Hz) dt=1.0/fs !Sample interval (s) - baud=1.0/tt !Keying rate (baud) nsps=0 if(nsec.eq.15) nsps=800 if(nsec.eq.30) nsps=1680 @@ -57,6 +56,7 @@ program fst280sim print*,'Invalid TR sequence length.' go to 999 endif + baud=12000.0/nsps !Keying rate (baud) nmax=nsec*12000 nz=nsps*NN nz2=nsps*NN2 @@ -78,7 +78,7 @@ program fst280sim write(*,*) write(*,'(a9,a37)') 'Message: ',msgsent37 - write(*,1000) f0,xdt,hmod,txt,snrdb + write(*,1000) f00,xdt,hmod,txt,snrdb 1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) write(*,*) if(i3.eq.1) then @@ -97,6 +97,7 @@ program fst280sim fsample=12000.0 icmplx=1 + f0=f00+1.5*hmod*baud call gen_fst280wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) k=nint((xdt+1.0)/dt)-nsps c0=cshift(c0,-k) @@ -135,7 +136,7 @@ program fst280sim open(10,file=trim(fname),status='unknown',access='stream') write(10) h,iwave !Save to *.wav file close(10) - write(*,1110) ifile,xdt,f0,snrdb,fname + write(*,1110) ifile,xdt,f00,snrdb,fname 1110 format(i4,f7.2,f8.2,f7.1,2x,a17) enddo diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index e47e251e5..0c8fb6f22 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -89,7 +89,7 @@ contains dt=1.0/fs !Sample interval (s) dt2=1.0/fs2 tt=nsps*dt !Duration of "itone" symbols (s) - + baud=1.0/tt nfft1=2*int(nmax/2) nh1=nfft1/2 allocate( r_data(1:nfft1+2) ) @@ -261,7 +261,8 @@ contains nsnr=nint(xsnr) iaptype=0 qual=0. - call this%callback(nutc,smax1,nsnr,xdt,fc_synced,msg, & + fsig=fc_synced - 1.5*hmod*baud + call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual) goto 2002 else From 1465ab6935d4649e82d5056b0a772faa75bca378 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 19 Jun 2020 13:39:10 -0500 Subject: [PATCH 034/239] Sync all signals and then de-dupe before decoding. Changes to sync threshold scheme. --- lib/fst280_decode.f90 | 57 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index e47e251e5..98b369deb 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -1,5 +1,4 @@ module fst280_decode - type :: fst280_decoder procedure(fst280_decode_callback), pointer :: callback contains @@ -41,7 +40,7 @@ contains complex, allocatable :: c_bigfft(:) !Complex waveform real, allocatable :: r_data(:) real llr(280),llra(280),llrb(280),llrc(280),llrd(280) - real candidates(100,3) + real candidates(100,4) real bitmetrics(328,4) integer hmod integer*1 apmask(280),cw(280) @@ -89,6 +88,7 @@ contains dt=1.0/fs !Sample interval (s) dt2=1.0/fs2 tt=nsps*dt !Duration of "itone" symbols (s) + baud=1/tt nfft1=2*int(nmax/2) nh1=nfft1/2 @@ -187,7 +187,40 @@ contains endif fc_synced = fc0 + fc2 dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + candidates(icand,3)=fc_synced + candidates(icand,4)=isbest + enddo +! remove duplicate candidates + do icand=1,ncand + fc=candidates(icand,3) + isbest=nint(candidates(icand,4)) + do ic2=1,ncand + fc2=candidates(ic2,3) + isbest2=nint(candidates(ic2,4)) + if(ic2.ne.icand .and. fc2.gt.0.0) then + if(abs(fc2-fc).lt.0.05*baud) then ! same frequency + if(abs(isbest2-isbest).le.2) then + candidates(ic2,3)=-1 + endif + endif + endif + enddo + enddo + + ic=0 + do icand=1,ncand + if(candidates(icand,3).gt.0) then + ic=ic+1 + candidates(ic,:)=candidates(icand,:) + endif + enddo + ncand=ic + + do icand=1,ncand + fc_synced=candidates(icand,3) + isbest=nint(candidates(icand,4)) + xdt=(isbest-nspsec)/fs2 call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) do ijitter=0,2 @@ -387,7 +420,7 @@ contains df1=fs/nfft1 baud=fs/nsps df2=baud/2.0 - nd=df1/df2 + nd=df2/df1 ndh=nd/2 ia=fa/df2 ib=fb/df2 @@ -398,19 +431,15 @@ contains s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo - call pctile(s(ia:ib),ib-ia+1,30,base) - s=s/base nh=hmod do i=ia,ib s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) - s2(i)=db(s2(i)) - 48.5 enddo + call pctile(s2(ia:ib),ib-ia+1,30,base) + s2=s2/base - if(hmod.eq.1) thresh=-29.5 !### temporaray? ### - if(hmod.eq.2) thresh=-27.0 - if(hmod.eq.4) thresh=-27.0 - if(hmod.eq.8) thresh=-27.0 - + thresh=1.25 + ncand=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 @@ -420,7 +449,11 @@ contains (s2(i).gt.thresh).and.ncand.lt.100) then ncand=ncand+1 candidates(ncand,1)=df2*i - candidates(ncand,2)=s2(i) + x=s2(i)-1 + snr=-99 +! temporary placeholder until we implement subtraction... + if(x.gt.0) snr=10*log10(x)-10*log10(2500.0*nsps/12000.0)+6.0 + candidates(ncand,2)=snr endif enddo From 7b62732a45f07a0e244cb9501704aa5645194322 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 19 Jun 2020 13:43:50 -0500 Subject: [PATCH 035/239] Fix size of candidates array. --- lib/fst280_decode.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 638872176..7347c5bc0 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -410,7 +410,7 @@ contains complex c_bigfft(0:nfft1/2) integer hmod - real candidates(100,3) + real candidates(100,4) real s(18000) real s2(18000) data nfft1z/-1/ From 87b79d0615b74c739c0b79e646c48814b3c939d9 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 15:02:05 -0400 Subject: [PATCH 036/239] OK, we can now transmit in FST280 mode. --- commons.h | 2 +- lib/fst280/gen_fst280wave.f90 | 5 ++-- widgets/mainwindow.cpp | 47 ++++++++++++++++++++++++++++++++--- widgets/mainwindow.h | 1 + wsjtx.pro | 1 + 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/commons.h b/commons.h index 24441ea06..f53bfff99 100644 --- a/commons.h +++ b/commons.h @@ -85,7 +85,7 @@ extern struct { } echocom_; extern struct { - float wave[606720]; + float wave[14278656]; int nslots; int nfreq; int i3bit[5]; diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index 7905544ef..944e06a36 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -1,4 +1,5 @@ -subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0,icmplx,cwave,wave) +subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & + icmplx,cwave,wave) real wave(nwave) complex cwave(nwave) @@ -11,7 +12,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0,icmplx,cwave,wav save first,twopi,dt,tsym if(first) then - allocate( pulse(3*nsps*fsample) ) + allocate(pulse(3*nsps*int(fsample))) twopi=8.0*atan(1.0) dt=1.0/fsample tsym=nsps/fsample diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index f6dce34af..cf5f39494 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -105,12 +105,18 @@ extern "C" { void genft4_(char* msg, int* ichk, char* msgsent, char ft4msgbits[], int itone[], fortran_charlen_t, fortran_charlen_t); + void genfst280_(char* msg, int* ichk, char* msgsent, char fst280msgbits[], + int itone[], int* iwspr, fortran_charlen_t, fortran_charlen_t); + void gen_ft8wave_(int itone[], int* nsym, int* nsps, float* bt, float* fsample, float* f0, float xjunk[], float wave[], int* icmplx, int* nwave); void gen_ft4wave_(int itone[], int* nsym, int* nsps, float* fsample, float* f0, float xjunk[], float wave[], int* icmplx, int* nwave); + void gen_fst280wave_(int itone[], int* nsym, int* nsps, int* nwave, float* fsample, + int* hmod, float* f0, int* icmplx, float xjunk[], float wave[]); + void gen4_(char* msg, int* ichk, char* msgsent, int itone[], int* itext, fortran_charlen_t, fortran_charlen_t); @@ -3801,7 +3807,8 @@ void MainWindow::guiUpdate() &m_currentMessageType, 22, 22); if(m_modeTx=="WSPR") genwspr_(message, msgsent, const_cast (itone), 22, 22); - if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4") { + if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4" + or m_modeTx=="FST280" or m_modeTx=="FST280W") { char MyCall[6]; char MyGrid[6]; ::memcpy(MyCall, (m_config.my_callsign()+" ").toLatin1(), sizeof MyCall); @@ -3862,8 +3869,26 @@ void MainWindow::guiUpdate() foxcom_.wave,&icmplx,&nwave); } if(m_modeTx=="FST280" or m_modeTx=="FST280W") { - // call genfst280() - // call gen_fst280wave() + int ichk=0; + int iwspr=0; + char fst280msgbits[101]; + genfst280_(message,&ichk,msgsent,const_cast (fst280msgbits), + const_cast(itone), &iwspr, 37, 37); + int hmod=int(pow(2.0,double(m_nSubMode))); + int nsps=800; + if(m_TRperiod==30) nsps=1680; + if(m_TRperiod==60) nsps=4000; + if(m_TRperiod==120) nsps=8400; + if(m_TRperiod==300) nsps=21504; + nsps=4*nsps; //48000 Hz sampling + int nsym=164; + float fsample=48000.0; + float dfreq=hmod*fsample/nsps; + float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; + int nwave=(nsym+2)*nsps; + int icmplx=0; + gen_fst280wave_(const_cast(itone),&nsym,&nsps,&nwave, + &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); } if(SpecOp::EU_VHF==m_config.special_op_id()) { @@ -7140,6 +7165,22 @@ void MainWindow::transmit (double snr) true, false, snr, m_TRperiod); } + if (m_modeTx == "FST280" or m_modeTx == "FST280W") { + m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); + toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. + int nsps=800; + if(m_TRperiod==30) nsps=1680; + if(m_TRperiod==60) nsps=4000; + if(m_TRperiod==120) nsps=8400; + if(m_TRperiod==300) nsps=21504; + int hmod=int(pow(2.0,double(m_nSubMode))); + double dfreq=hmod*12000.0/nsps; + double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; + Q_EMIT sendMessage (NUM_FST280_SYMBOLS,double(nsps),f0,toneSpacing, + m_soundOutput,m_config.audio_output_channel(), + true, false, snr, m_TRperiod); + } + if (m_modeTx == "QRA64") { if(m_nSubMode==0) toneSpacing=12000.0/6912.0; if(m_nSubMode==1) toneSpacing=2*12000.0/6912.0; diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 779d76da4..ac8c22d15 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -49,6 +49,7 @@ #define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync #define NUM_FT8_SYMBOLS 79 #define NUM_FT4_SYMBOLS 105 +#define NUM_FST280_SYMBOLS 164 //280/2 data + 6*4 sync #define NUM_CW_SYMBOLS 250 #define TX_SAMPLE_RATE 48000 #define N_WIDGETS 33 diff --git a/wsjtx.pro b/wsjtx.pro index 02a69d33c..d8d2b0949 100644 --- a/wsjtx.pro +++ b/wsjtx.pro @@ -54,6 +54,7 @@ include(logbook/logbook.pri) include(widgets/widgets.pri) include(Decoder/decodedtext.pri) include(Detector/Detector.pri) +include(Modulator/Modulator.pri) SOURCES += \ Radio.cpp NetworkServerLookup.cpp revision_utils.cpp \ From dff2b7e146fa564a74a864e84c2991a00a483a49 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 15:54:59 -0400 Subject: [PATCH 037/239] Add code to sort FST280 candidates by strength and return only the top few. Temporary? --- lib/fst280_decode.f90 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 7347c5bc0..a0e0c73dd 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -410,7 +410,10 @@ contains complex c_bigfft(0:nfft1/2) integer hmod + integer indx(100) real candidates(100,4) + real candidates0(100,4) + real snr_cand(100) real s(18000) real s2(18000) data nfft1z/-1/ @@ -457,6 +460,17 @@ contains endif enddo + snr_cand=0. + snr_cand(1:ncand)=candidates(1:ncand,2) + call indexx(snr_cand,ncand,indx) + nmax=5 + do i=1,min(ncand,nmax) + j=indx(ncand+1-i) + candidates0(i,1:4)=candidates(j,1:4) + enddo + candidates(1:nmax,1:4)=candidates0(1:nmax,1:4) + candidates(nmax+1:,1:4)=0. + return end subroutine get_candidates_fst280 From 28746dd0b69f8764e2f17445e8f0654223a8495d Mon Sep 17 00:00:00 2001 From: K9AN Date: Fri, 19 Jun 2020 16:49:26 -0500 Subject: [PATCH 038/239] Need to reallocate pulse() when nsps changes. --- lib/fst280/gen_fst280wave.f90 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index 944e06a36..0735c7bf3 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -9,9 +9,13 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & integer itone(nsym) logical first data first/.true./ - save first,twopi,dt,tsym + data nsps0/-99/ + save first,twopi,dt,tsym,nsps0 - if(first) then + if(first.or.nsps.ne.nsps0) then + if(allocated(pulse)) then + deallocate(pulse) + endif allocate(pulse(3*nsps*int(fsample))) twopi=8.0*atan(1.0) dt=1.0/fsample @@ -22,6 +26,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & pulse(i)=gfsk_pulse(2.0,tt) enddo first=.false. + nsps0=nsps endif ! Compute the smoothed frequency waveform. @@ -38,7 +43,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & ! Calculate and insert the audio waveform phi=0.0 dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 - wave=0. + if(icmplx.eq.0) wave=0. if(icmplx.eq.1) cwave=0. k=0 do j=0,(nsym+2)*nsps-1 From f2b460231b438eeb3367a697ea9fea11967582e5 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 19 Jun 2020 19:17:05 -0400 Subject: [PATCH 039/239] Should allocate pulse(1:3*nsps), not pulse(1:3*nsps*fsample) ! --- lib/fst280/gen_fst280wave.f90 | 8 +++----- lib/ft8/foxgen.f90 | 26 +------------------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index 0735c7bf3..9245af406 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -13,10 +13,8 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & save first,twopi,dt,tsym,nsps0 if(first.or.nsps.ne.nsps0) then - if(allocated(pulse)) then - deallocate(pulse) - endif - allocate(pulse(3*nsps*int(fsample))) + if(allocated(pulse)) deallocate(pulse) + allocate(pulse(1:3*nsps)) twopi=8.0*atan(1.0) dt=1.0/fsample tsym=nsps/fsample @@ -42,7 +40,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & ! Calculate and insert the audio waveform phi=0.0 - dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 + dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 if(icmplx.eq.0) wave=0. if(icmplx.eq.1) cwave=0. k=0 diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 7492a6f70..703da0ef9 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -15,7 +15,7 @@ subroutine foxgen() ! common block. parameter (NN=79,ND=58,NSPS=4*1920) - parameter (NWAVE=NN*NSPS,NFFT=614400,NH=NFFT/2) + parameter (NWAVE=14278656,NFFT=614400,NH=NFFT/2) character*40 cmsg character*37 msg,msgsent integer itone(79) @@ -60,34 +60,10 @@ subroutine foxgen() peak1=maxval(abs(wave)) wave=wave/peak1 -! call plotspec(1,wave) !Plot the spectrum - -! Apply compression -! rms=sqrt(dot_product(wave,wave)/kz) -! wave=wave/rms -! do i=1,NWAVE -! wave(i)=h1(wave(i)) -! enddo -! peak2=maxval(abs(wave)) -! wave=wave/peak2 - -! call plotspec(2,wave) !Plot the spectrum - width=50.0 call foxfilt(nslots,nfreq,width,wave) peak3=maxval(abs(wave)) wave=wave/peak3 - -! nadd=1000 -! j=0 -! do i=1,NWAVE,nadd -! sx=dot_product(wave(i:i+nadd-1),wave(i:i+nadd-1)) -! j=j+1 -! write(30,3001) j,sx/nadd -!3001 format(i8,f12.6) -! enddo - -! call plotspec(3,wave) !Plot the spectrum return end subroutine foxgen From e78f1abcedccca04eaddc6cefba01da2fc615cae Mon Sep 17 00:00:00 2001 From: K9AN Date: Fri, 19 Jun 2020 20:56:50 -0500 Subject: [PATCH 040/239] Make sure that ncand is correct even when the number of candidates has been limited. --- lib/fst280_decode.f90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index a0e0c73dd..04806a27d 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -441,9 +441,10 @@ contains call pctile(s2(ia:ib),ib-ia+1,30,base) s2=s2/base - thresh=1.25 + thresh=1.4 ncand=0 + candidates=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 do i=ia,ib @@ -464,7 +465,8 @@ contains snr_cand(1:ncand)=candidates(1:ncand,2) call indexx(snr_cand,ncand,indx) nmax=5 - do i=1,min(ncand,nmax) + ncand=min(ncand,nmax) + do i=1,ncand j=indx(ncand+1-i) candidates0(i,1:4)=candidates(j,1:4) enddo From 644a570cb995b638c3fe9c75487e90a168cc8046 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 20 Jun 2020 12:37:37 -0500 Subject: [PATCH 041/239] Enable sync checks on candidates. --- lib/fst280/get_fst280_bitmetrics.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index 50568210f..bba000d59 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -72,10 +72,10 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) nsync=is1+is2+is3 !Number of correct hard sync symbols, 0-24 badsync=.false. -! if(nsync .lt. 8) then -! badsync=.true. -! return -! endif + if(nsync .lt. 8) then + badsync=.true. + return + endif bitmetrics=0.0 do nseq=1,4 !Try coherent sequences of 1, 2, and 4 symbols From f8d7489b4ed92148d3afa622d8b027fb9864206d Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 20 Jun 2020 13:47:32 -0400 Subject: [PATCH 042/239] Fix many odds & ends for merging FST280 properly into the GUI. --- lib/77bit/packjt77.f90 | 2 +- lib/decoder.f90 | 19 ++++++++++++++----- lib/fst280_decode.f90 | 5 +++-- widgets/displaytext.cpp | 6 ++++-- widgets/displaytext.h | 2 +- widgets/mainwindow.cpp | 21 +++++++++++---------- widgets/plotter.cpp | 15 ++++++++++++--- 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 2b1a60bf3..1937892bc 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -897,7 +897,7 @@ subroutine pack77_03(nwords,w,i3,n3,c77) ntx=-1 j=len(trim(w(nwords-1)))-1 - read(w(nwords-1)(1:j),*,err=1) ntx !Number of transmitters + read(w(nwords-1)(1:j),*,err=1,end=1) ntx !Number of transmitters 1 if(ntx.lt.1 .or. ntx.gt.32) return nclass=ichar(w(nwords-1)(j+1:j+1))-ichar('A') diff --git a/lib/decoder.f90 b/lib/decoder.f90 index c737a2ca6..5db74e39b 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -678,7 +678,8 @@ contains return end subroutine ft4_decoded - subroutine fst280_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap,qual) + subroutine fst280_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & + qual,ntrperiod) use fst280_decode implicit none @@ -692,6 +693,7 @@ contains character(len=37), intent(in) :: decoded integer, intent(in) :: nap real, intent(in) :: qual + integer, intent(in) :: ntrperiod character*2 annot character*37 decoded0 @@ -702,10 +704,17 @@ contains if(qual.lt.0.17) decoded0(37:37)='?' endif - write(*,1001) nutc,nsnr,dt,nint(freq),decoded0,annot -1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) - write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 -1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') + if(ntrperiod.lt.60) then + write(*,1001) nutc,nsnr,dt,nint(freq),decoded0,annot +1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) + write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 +1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') + else + write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot +1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2) + write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 +1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') + endif call flush(6) call flush(13) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index a0e0c73dd..377332cb7 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -7,7 +7,7 @@ module fst280_decode abstract interface subroutine fst280_decode_callback (this,nutc,sync,nsnr,dt,freq, & - decoded,nap,qual) + decoded,nap,qual,ntrperiod) import fst280_decoder implicit none class(fst280_decoder), intent(inout) :: this @@ -19,6 +19,7 @@ module fst280_decode character(len=37), intent(in) :: decoded integer, intent(in) :: nap real, intent(in) :: qual + integer, intent(in) :: ntrperiod end subroutine fst280_decode_callback end interface @@ -295,7 +296,7 @@ contains qual=0. fsig=fc_synced - 1.5*hmod*baud call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual) + iaptype,qual,ntrperiod) goto 2002 else cycle diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index f0f17f648..47478e346 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -451,7 +451,8 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con } -void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq,bool bFastMode) +void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq, + bool bFastMode, double TRperiod) { QString t1=" @ "; if(modeTx=="FT4") t1=" + "; @@ -459,10 +460,11 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx if(modeTx=="JT4") t1=" $ "; if(modeTx=="JT65") t1=" # "; if(modeTx=="MSK144") t1=" & "; + if(modeTx=="FST280") t1=" ` "; QString t2; t2 = t2.asprintf("%4d",txFreq); QString t; - if(bFastMode or modeTx=="FT8" or modeTx=="FT4") { + if(bFastMode or modeTx=="FT8" or modeTx=="FT4" or (TRperiod<60)) { t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \ " Tx " + t2 + t1 + text; } else if(modeTx.mid(0,6)=="FT8fox") { diff --git a/widgets/displaytext.h b/widgets/displaytext.h index fb8bb6134..d4adc3d2c 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -31,7 +31,7 @@ public: void displayDecodedText(DecodedText const& decodedText, QString const& myCall, QString const& mode, bool displayDXCCEntity, LogBook const& logBook, QString const& currentBand=QString {}, bool ppfx=false, bool bCQonly=false); - void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode); + void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode, double TRperiod); void displayQSY(QString text); void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {}); void new_period (); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index cf5f39494..0d996fd6b 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -2890,9 +2890,9 @@ void MainWindow::decode() //decode() imin=imin % 60; if(m_TRperiod>=60) imin=imin - (imin % (int(m_TRperiod)/60)); dec_data.params.nutc=100*ihr + imin; - if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9 or m_mode=="FT8" or m_mode=="FT4") { + if(m_TRperiod < 60) { qint64 ms=1000.0*(2.0-m_TRperiod); - if(m_mode=="FT4") ms=1000.0*(2.0-m_TRperiod); + if(m_mode=="FST280") ms=1000.0*(6.0-m_TRperiod); //Adjust for FT8 early decode: if(m_mode=="FT8" and m_ihsym==m_earlyDecode and !m_diskData) ms+=(m_hsymStop-m_earlyDecode)*288; if(m_mode=="FT8" and m_ihsym==m_earlyDecode2 and !m_diskData) ms+=(m_hsymStop-m_earlyDecode2)*288; @@ -3244,7 +3244,7 @@ void MainWindow::readFromStdout() //readFromStdout //Right (Rx Frequency) window bool bDisplayRight=bAvgMsg; int audioFreq=decodedtext.frequencyOffset(); - if(m_mode=="FT8" or m_mode=="FT4") { + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") { auto const& parts = decodedtext.string().remove("<").remove(">") .split (' ', SkipEmptyParts); if (parts.size() > 6) { @@ -3327,7 +3327,8 @@ void MainWindow::readFromStdout() //readFromStdout //### I think this is where we are preventing Hounds from spotting Fox ### if(m_mode!="FT8" or (SpecOp::HOUND != m_config.special_op_id())) { - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="QRA64" or m_mode=="JT4" or m_mode=="JT65" or m_mode=="JT9") { + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="QRA64" or m_mode=="JT4" + or m_mode=="JT65" or m_mode=="JT9" or m_mode=="FST280") { auto_sequence (decodedtext, 25, 50); } @@ -3927,7 +3928,7 @@ void MainWindow::guiUpdate() write_all("Tx",m_currentMessage); if (m_config.TX_messages ()) { ui->decodedTextBrowser2->displayTransmittedText(m_currentMessage,m_modeTx, - ui->TxFreqSpinBox->value(),m_bFastMode); + ui->TxFreqSpinBox->value(),m_bFastMode,m_TRperiod); } } @@ -4030,7 +4031,7 @@ void MainWindow::guiUpdate() if (m_config.TX_messages () && !m_tune && SpecOp::FOX!=m_config.special_op_id()) { ui->decodedTextBrowser2->displayTransmittedText(current_message, m_modeTx, - ui->TxFreqSpinBox->value(),m_bFastMode); + ui->TxFreqSpinBox->value(),m_bFastMode,m_TRperiod); } // } @@ -5824,12 +5825,13 @@ void MainWindow::on_actionFST280_triggered() WSPR_config(false); bool bVHF=m_config.enable_VHF_features(); // 012345678901234567890123456789012 - displayWidgets(nWidgets("111011000000111100010000000000000")); + displayWidgets(nWidgets("111011000100111100010000000100000")); setup_status_bar (bVHF); m_TRperiod = ui->sbTR->value (); ui->sbTR->setMinimum(15); ui->sbTR->setMaximum(300); on_sbTR_valueChanged(ui->sbTR->value()); + ui->cbAutoSeq->setChecked(true); statusChanged(); } @@ -5872,7 +5874,6 @@ void MainWindow::on_actionFT4_triggered() m_wideGraph->setModeTx(m_modeTx); m_send_RR73=true; VHF_features_enabled(bVHF); -// ui->cbAutoSeq->setChecked(false); m_fastGraph->hide(); m_wideGraph->show(); ui->decodedTextLabel2->setText(" UTC dB DT Freq " + tr ("Message")); @@ -8256,7 +8257,7 @@ void MainWindow::on_cbFirst_toggled(bool b) void MainWindow::on_cbAutoSeq_toggled(bool b) { if(!b) ui->cbFirst->setChecked(false); - ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4") and b); + ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") and b); } void MainWindow::on_measure_check_box_stateChanged (int state) @@ -8819,7 +8820,7 @@ void MainWindow::foxGenWaveform(int i,QString fm) QString txModeArg; txModeArg = txModeArg.asprintf("FT8fox %d",i+1); ui->decodedTextBrowser2->displayTransmittedText(fm.trimmed(), txModeArg, - ui->TxFreqSpinBox->value()+60*i,m_bFastMode); + ui->TxFreqSpinBox->value()+60*i,m_bFastMode,m_TRperiod); foxcom_.i3bit[i]=0; if(fm.indexOf("<")>0) foxcom_.i3bit[i]=1; strncpy(&foxcom_.cmsg[i][0],fm.toLatin1(),40); //Copy this message into cmsg[i] diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index c5ade99a5..cf1e70cd1 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -415,7 +415,16 @@ void CPlotter::DrawOverlay() //DrawOverlay() float bw=9.0*12000.0/m_nsps; //JT9 if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 - + if(m_mode=="FST280") { + int h=int(pow(2.0,m_nSubMode)); + int nsps=800; + if(m_TRperiod==30) nsps=1680; + if(m_TRperiod==60) nsps=4000; + if(m_TRperiod==120) nsps=8400; + if(m_TRperiod==300) nsps=21504; + float baud=12000.0/nsps; + bw=3.0*h*baud; + } if(m_mode=="JT4") { //JT4 bw=3*11025.0/2520.0; //Max tone spacing (3/4 of actual BW) if(m_nSubMode==1) bw=2*bw; @@ -492,7 +501,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() int yTxTop=12; int yRxBottom=yTxTop + 2*yh + 4; if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" - or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4") { + or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") { if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) { painter0.setPen(penGreen); @@ -529,7 +538,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8" - or m_mode=="FT4") { + or m_mode=="FT4" or m_mode=="FST280") { painter0.setPen(penRed); x1=XfromFreq(m_txFreq); x2=XfromFreq(m_txFreq+bw); From 066d2585bcee136dc4956d056de394e0947625af Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 20 Jun 2020 14:17:05 -0400 Subject: [PATCH 043/239] Revert "Enable sync checks on candidates." This reverts commit 644a570cb995b638c3fe9c75487e90a168cc8046. --- lib/fst280/get_fst280_bitmetrics.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index bba000d59..50568210f 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -72,10 +72,10 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) nsync=is1+is2+is3 !Number of correct hard sync symbols, 0-24 badsync=.false. - if(nsync .lt. 8) then - badsync=.true. - return - endif +! if(nsync .lt. 8) then +! badsync=.true. +! return +! endif bitmetrics=0.0 do nseq=1,4 !Try coherent sequences of 1, 2, and 4 symbols From 17d1bc92dc9923330fb2f57e128eaee02899c7e4 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 20 Jun 2020 14:17:34 -0400 Subject: [PATCH 044/239] Revert "Make sure that ncand is correct even when the number of candidates has been limited." This reverts commit e78f1abcedccca04eaddc6cefba01da2fc615cae. --- lib/fst280_decode.f90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index a0e4b4a0c..377332cb7 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -442,10 +442,9 @@ contains call pctile(s2(ia:ib),ib-ia+1,30,base) s2=s2/base - thresh=1.4 + thresh=1.25 ncand=0 - candidates=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 do i=ia,ib @@ -466,8 +465,7 @@ contains snr_cand(1:ncand)=candidates(1:ncand,2) call indexx(snr_cand,ncand,indx) nmax=5 - ncand=min(ncand,nmax) - do i=1,ncand + do i=1,min(ncand,nmax) j=indx(ncand+1-i) candidates0(i,1:4)=candidates(j,1:4) enddo From 0e935f0cf7fcba2a6e54b7c8d7f15a15b7551fc7 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 20 Jun 2020 15:41:52 -0400 Subject: [PATCH 045/239] More tweaks to FST280 decoding. Suppress blank free text msgs. --- lib/77bit/packjt77.f90 | 4 ++++ lib/fst280/get_fst280_bitmetrics.f90 | 8 ++++---- lib/fst280_decode.f90 | 15 +++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 1937892bc..9819600d8 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -281,6 +281,10 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) call unpacktext77(c77(1:71),msg(1:13)) msg(14:)=' ' msg=adjustl(msg) + if(msg(1:1).eq.' ') then + unpk77_success=.false. + return + endif else if(i3.eq.0 .and. n3.eq.1) then ! 0.1 K1ABC RR73; W9XYZ -11 28 28 10 5 71 DXpedition Mode diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index 50568210f..bba000d59 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -72,10 +72,10 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) nsync=is1+is2+is3 !Number of correct hard sync symbols, 0-24 badsync=.false. -! if(nsync .lt. 8) then -! badsync=.true. -! return -! endif + if(nsync .lt. 8) then + badsync=.true. + return + endif bitmetrics=0.0 do nseq=1,4 !Try coherent sequences of 1, 2, and 4 symbols diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 377332cb7..a0631ae20 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -232,6 +232,7 @@ contains cframe=c2(is0:is0+164*nss-1) s2=sum(cframe*conjg(cframe)) cframe=cframe/sqrt(s2) + bitmetrics=0 call get_fst280_bitmetrics(cframe,nss,hmod,bitmetrics,badsync) hbits=0 @@ -243,7 +244,7 @@ contains ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 -! if(nsync_qual.lt. 20) cycle + if(nsync_qual.lt. 30) cycle !### Value ?? ### scalefac=2.83 llra( 1:140)=bitmetrics( 17:156, 1) @@ -442,9 +443,10 @@ contains call pctile(s2(ia:ib),ib-ia+1,30,base) s2=s2/base - thresh=1.25 + thresh=1.4 ncand=0 + candidates=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 do i=ia,ib @@ -464,13 +466,14 @@ contains snr_cand=0. snr_cand(1:ncand)=candidates(1:ncand,2) call indexx(snr_cand,ncand,indx) - nmax=5 - do i=1,min(ncand,nmax) + nmax=min(ncand,5) + do i=1,nmax j=indx(ncand+1-i) candidates0(i,1:4)=candidates(j,1:4) enddo - candidates(1:nmax,1:4)=candidates0(1:nmax,1:4) - candidates(nmax+1:,1:4)=0. + ncand=nmax + candidates(1:ncand,1:4)=candidates0(1:ncand,1:4) + candidates(ncand+1:,1:4)=0. return end subroutine get_candidates_fst280 From f03f411733520a5ac43f235fe080781804dc6d2e Mon Sep 17 00:00:00 2001 From: K9AN Date: Sun, 21 Jun 2020 08:48:34 -0500 Subject: [PATCH 046/239] Changes to enable Fast and Normal decode settings. NB - max number of candidates has been increased to 20. --- lib/fst280/get_fst280_bitmetrics.f90 | 4 +-- lib/fst280_decode.f90 | 40 +++++++++++++++++----------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index bba000d59..f9f5f1b7e 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -1,4 +1,4 @@ -subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) +subroutine get_fst280_bitmetrics(cd,nss,hmod,nmax,bitmetrics,badsync) include 'fst280_params.f90' complex cd(0:NN*nss-1) @@ -78,7 +78,7 @@ subroutine get_fst280_bitmetrics(cd,nss,hmod,bitmetrics,badsync) endif bitmetrics=0.0 - do nseq=1,4 !Try coherent sequences of 1, 2, and 4 symbols + do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols if(nseq.eq.1) nsym=1 if(nseq.eq.2) nsym=2 if(nseq.eq.3) nsym=4 diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index a0631ae20..366e39706 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -100,10 +100,24 @@ contains allocate( cframe(0:164*nss-1) ) npts=nmax - fa=nfa - fb=nfb + fa=max(100,nfa) + fb=min(4800,nfb) -! The big fft is done once and is used for calculating the smoothed spectrum + if(ndeep.eq.3) then + ntmax=4 ! number of block sizes to try + jittermax=2 + norder=3 + elseif(ndeep.eq.2) then + ntmax=3 + jittermax=2 + norder=3 + elseif(ndeep.eq.1) then + ntmax=1 + jittermax=2 + norder=2 + endif + + ! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. r_data(1:nfft1)=iwave(1:nfft1) r_data(nfft1+1:nfft1+2)=0.0 @@ -113,7 +127,7 @@ contains ! Get first approximation of candidate frequencies call get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & ncand,candidates) - + ndecodes=0 isbest1=0 isbest8=0 @@ -173,16 +187,12 @@ contains if(smax8/smax1 .lt. 0.65 ) then fc2=fc21 isbest=isbest1 - ntmax=4 if(hmod.gt.1) ntmax=1 - ntmin=1 njitter=2 else fc2=fc28 isbest=isbest8 - ntmax=4 if(hmod.gt.1) ntmax=1 - ntmin=1 njitter=2 endif fc_synced = fc0 + fc2 @@ -223,7 +233,7 @@ contains xdt=(isbest-nspsec)/fs2 call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) - do ijitter=0,2 + do ijitter=0,jittermax if(ijitter.eq.0) ioffset=0 if(ijitter.eq.1) ioffset=1 if(ijitter.eq.2) ioffset=-1 @@ -233,7 +243,8 @@ contains s2=sum(cframe*conjg(cframe)) cframe=cframe/sqrt(s2) bitmetrics=0 - call get_fst280_bitmetrics(cframe,nss,hmod,bitmetrics,badsync) + call get_fst280_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,badsync) + if(badsync) cycle hbits=0 where(bitmetrics(:,1).ge.0) hbits=1 @@ -261,7 +272,7 @@ contains llrd=scalefac*llrd apmask=0 - do itry=ntmax,ntmin,-1 + do itry=1,ntmax if(itry.eq.1) llr=llra if(itry.eq.2) llr=llrb if(itry.eq.3) llr=llrc @@ -272,13 +283,13 @@ contains if(iwspr.eq.0) then maxosd=2 call timer('d280_101',0) - call decode280_101(llr,Keff,maxosd,ndeep,apmask,message101, & + call decode280_101(llr,Keff,maxosd,norder,apmask,message101, & cw,ntype,nharderrors,dmin) call timer('d280_101',1) else maxosd=2 call timer('d280_74 ',0) - call decode280_74(llr,Keff,maxosd,ndeep,apmask,message74,cw, & + call decode280_74(llr,Keff,maxosd,norder,apmask,message74,cw, & ntype,nharderrors,dmin) call timer('d280_74 ',1) endif @@ -466,7 +477,7 @@ contains snr_cand=0. snr_cand(1:ncand)=candidates(1:ncand,2) call indexx(snr_cand,ncand,indx) - nmax=min(ncand,5) + nmax=min(ncand,20) do i=1,nmax j=indx(ncand+1-i) candidates0(i,1:4)=candidates(j,1:4) @@ -474,7 +485,6 @@ contains ncand=nmax candidates(1:ncand,1:4)=candidates0(1:ncand,1:4) candidates(ncand+1:,1:4)=0. - return end subroutine get_candidates_fst280 From ad4fac6b3d002f831b943d6e853e98f3b13f57e4 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 10:33:36 -0400 Subject: [PATCH 047/239] Implement "Single decode" for FST280. --- lib/decoder.f90 | 3 ++- lib/fst280_decode.f90 | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 5db74e39b..b51a3f906 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -192,7 +192,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) call timer('dec280 ',0) call my_fst280%decode(fst280_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & - params%nsubmode,params%ndepth,params%ntr) + params%nsubmode,params%ndepth,params%ntr,params%nexp_decode, & + params%ntol) call timer('dec280 ',1) go to 800 endif diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 366e39706..865602e55 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -26,7 +26,7 @@ module fst280_decode contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & - nfa,nfb,nsubmode,ndeep,ntrperiod) + nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol) use timer_module, only: timer use packjt77 @@ -47,7 +47,7 @@ contains integer*1 apmask(280),cw(280) integer*1 hbits(328) integer*1 message101(101),message74(74) - logical badsync,unpk77_success + logical badsync,unpk77_success,single_decode integer*2 iwave(300*12000) this%callback => callback @@ -56,6 +56,7 @@ contains Keff=91 iwspr=0 nmax=15*12000 + single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then nsps=800 @@ -100,8 +101,13 @@ contains allocate( cframe(0:164*nss-1) ) npts=nmax - fa=max(100,nfa) - fb=min(4800,nfb) + if(single_decode) then + fa=max(100,nfqso-ntol) + fb=min(4800,nfqso+ntol) + else + fa=max(100,nfa) + fb=min(4800,nfb) + endif if(ndeep.eq.3) then ntmax=4 ! number of block sizes to try From 37b1b7aa6fec424d7115bc91c13648b0bb642293 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 10:34:24 -0400 Subject: [PATCH 048/239] More of "Single Decode". Also, update m_mode in Wide Graph when switching to FST280. --- widgets/mainwindow.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 0d996fd6b..686259ee4 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5825,13 +5825,15 @@ void MainWindow::on_actionFST280_triggered() WSPR_config(false); bool bVHF=m_config.enable_VHF_features(); // 012345678901234567890123456789012 - displayWidgets(nWidgets("111011000100111100010000000100000")); + displayWidgets(nWidgets("111111000100111100010000000100000")); setup_status_bar (bVHF); m_TRperiod = ui->sbTR->value (); ui->sbTR->setMinimum(15); ui->sbTR->setMaximum(300); on_sbTR_valueChanged(ui->sbTR->value()); ui->cbAutoSeq->setChecked(true); + m_wideGraph->setMode(m_mode); + m_wideGraph->setModeTx(m_modeTx); statusChanged(); } @@ -5850,6 +5852,8 @@ void MainWindow::on_actionFST280W_triggered() ui->sbTR->setMinimum(120); ui->sbTR->setMaximum(300); ui->sbSubmode->setMaximum(3); + m_wideGraph->setMode(m_mode); + m_wideGraph->setModeTx(m_modeTx); statusChanged(); } From f04c9d2267e9fcc13facd6471cd510bb3bc83406 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 10:54:24 -0400 Subject: [PATCH 049/239] Mark the FST280 Ftol range on the waterfall scale. --- widgets/plotter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index cf1e70cd1..c25ba6306 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -330,7 +330,6 @@ void CPlotter::DrawOverlay() //DrawOverlay() double df = m_binsPerPixel*m_fftBinWidth; QPen penOrange(QColor(255,165,0),3); -// QPen penGreen(Qt::green, 3); //Mark Tol range with green line QPen penGreen(QColor(15,153,105), 3); //Mark Tol range or BW with dark green line QPen penRed(Qt::red, 3); //Mark Tx freq with red QPainter painter(&m_OverlayPixmap); @@ -532,6 +531,11 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,yRxBottom-yh,x1,yRxBottom); painter0.drawLine(x1,yRxBottom,x2,yRxBottom); painter0.drawLine(x2,yRxBottom-yh,x2,yRxBottom); + if(m_mode=="FST280") { + x1=XfromFreq(m_rxFreq-m_tol); + x2=XfromFreq(m_rxFreq+m_tol); + painter0.drawLine(x1,29,x2,29); // Mark the Tol range + } } } From 3a16399857980496af8c0d951aa6f180b3eeb18f Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 11:08:46 -0400 Subject: [PATCH 050/239] Don't send "" twice for FST280. --- lib/fst280_decode.f90 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 865602e55..66d38bc48 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -323,9 +323,7 @@ contains enddo ! metrics enddo ! istart jitter 2002 continue - enddo !candidate list - write(*,1120) -1120 format("") + enddo !candidate list!ws return end subroutine decode From 956aa2dfc59367ff11a58b4a1bc0de5d6f3ecd32 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 11:27:30 -0400 Subject: [PATCH 051/239] Call switch_mode() to repopulate bandComboBox after switching to FST280. --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 686259ee4..b3cc32127 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5834,6 +5834,7 @@ void MainWindow::on_actionFST280_triggered() ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); + switch_mode (Modes::FST280); statusChanged(); } @@ -5854,6 +5855,7 @@ void MainWindow::on_actionFST280W_triggered() ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); + switch_mode (Modes::FST280W); statusChanged(); } From 79c437f69a770d9cb82d0fdee95733fb23a9479b Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sun, 21 Jun 2020 12:40:38 -0500 Subject: [PATCH 052/239] Implement de-duping for FST280. --- lib/fst280_decode.f90 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 66d38bc48..0d10eb095 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -34,6 +34,7 @@ contains parameter (MAXCAND=100) class(fst280_decoder), intent(inout) :: this procedure(fst280_decode_callback) :: callback + character*37 decodes(100) character*37 msg character*77 c77 complex, allocatable :: c2(:) @@ -135,6 +136,8 @@ contains ncand,candidates) ndecodes=0 + decodes=' ' + isbest1=0 isbest8=0 fc21=0. @@ -308,7 +311,14 @@ contains c77(51:77)='000000000000000000000110000' call unpack77(c77,0,msg,unpk77_success) endif - if(nharderrors .ge.0 .and. unpk77_success) then + if(unpk77_success) then + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.msg) idupe=1 + enddo + if(idupe.eq.1) exit + ndecodes=ndecodes+1 + decodes(ndecodes)=msg nsnr=nint(xsnr) iaptype=0 qual=0. From 1f7d8545f3f24854fd0d6e9d631f486fab8730c6 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 13:49:37 -0400 Subject: [PATCH 053/239] Tx line to ALL.TXT should be trimmed(). --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b3cc32127..750e40520 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -8983,7 +8983,7 @@ void MainWindow::write_all(QString txRx, QString message) QFile f{m_config.writeable_data_dir().absoluteFilePath(file_name)}; if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { QTextStream out(&f); - out << line + out << line.trimmed() #if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0) << Qt::endl #else From 501cb449230add9c64e5f562775ec420888c7824 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 14:38:40 -0400 Subject: [PATCH 054/239] Clean up git workspace. --- .gitignore | 5 ++++ Decoder/decodedtext.pri | 3 ++ Detector/Detector.pri | 3 ++ Modulator/Modulator.pri | 3 ++ lib/77bit/call_to_c28.f90 | 21 ++++++++++++++ lib/77bit/free_text.f90 | 58 +++++++++++++++++++++++++++++++++++++ lib/77bit/nonstd_to_c58.f90 | 13 +++++++++ lib/t6.f90 | 56 ----------------------------------- 8 files changed, 106 insertions(+), 56 deletions(-) create mode 100644 Decoder/decodedtext.pri create mode 100644 Detector/Detector.pri create mode 100644 Modulator/Modulator.pri create mode 100644 lib/77bit/call_to_c28.f90 create mode 100644 lib/77bit/free_text.f90 create mode 100644 lib/77bit/nonstd_to_c58.f90 delete mode 100644 lib/t6.f90 diff --git a/.gitignore b/.gitignore index 3ffc4aed5..2bd99ec81 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,8 @@ jnq* *.txt cmake-build-debug cmake-build-release +CMakeFiles +fnd +lib/77bit/tmp +lib/tmp +lib/ftrsd diff --git a/Decoder/decodedtext.pri b/Decoder/decodedtext.pri new file mode 100644 index 000000000..6aa33dc36 --- /dev/null +++ b/Decoder/decodedtext.pri @@ -0,0 +1,3 @@ +SOURCES += Decoder/decodedtext.cpp + +HEADERS += Decoder/decodedtext.h diff --git a/Detector/Detector.pri b/Detector/Detector.pri new file mode 100644 index 000000000..a98051194 --- /dev/null +++ b/Detector/Detector.pri @@ -0,0 +1,3 @@ +SOURCES += Detector/Detector.cpp + +HEADERS += Detector/Detector.hpp diff --git a/Modulator/Modulator.pri b/Modulator/Modulator.pri new file mode 100644 index 000000000..a90a55f7a --- /dev/null +++ b/Modulator/Modulator.pri @@ -0,0 +1,3 @@ +SOURCES += Modulator/Modulator.cpp + +HEADERS += Modulator/Mpdulator.hpp diff --git a/lib/77bit/call_to_c28.f90 b/lib/77bit/call_to_c28.f90 new file mode 100644 index 000000000..96930c575 --- /dev/null +++ b/lib/77bit/call_to_c28.f90 @@ -0,0 +1,21 @@ +program call_to_c28 + parameter (NTOKENS=2063592,MAX22=4194304) + character*6 call_std + character a1*37,a2*36,a3*10,a4*27 + data a1/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ + data a2/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ + data a3/'0123456789'/ + data a4/' ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ + ! call_std must be right adjusted, length 6 + call_std=' K1ABC' !Redefine as needed + i1=index(a1,call_std(1:1))-1 + i2=index(a2,call_std(2:2))-1 + i3=index(a3,call_std(3:3))-1 + i4=index(a4,call_std(4:4))-1 + i5=index(a4,call_std(5:5))-1 + i6=index(a4,call_std(6:6))-1 + n28=NTOKENS + MAX22 + 36*10*27*27*27*i1 + 10*27*27*27*i2 + & + 27*27*27*i3 + 27*27*i4 + 27*i5 + i6 + write(*,1000) call_std,n28 +1000 format('Callsign: ',a6,2x,'c28 as decimal integer:',i10) +end program call_to_c28 diff --git a/lib/77bit/free_text.f90 b/lib/77bit/free_text.f90 new file mode 100644 index 000000000..c7e668234 --- /dev/null +++ b/lib/77bit/free_text.f90 @@ -0,0 +1,58 @@ +program free_text + character*13 c13,w + character*71 f71 + character*42 c + character*1 qa(10),qb(10) + data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?'/ + c13='TNX BOB 73 GL' !Redefine as needed + call mp_short_init + qa=char(0) + w=adjustr(c13) + do i=1,13 + j=index(c,w(i:i))-1 + if(j.lt.0) j=0 + call mp_short_mult(qb,qa(2:10),9,42) !qb(1:9)=42*qa(2:9) + call mp_short_add(qa,qb(2:10),9,j) !qa(1:9)=qb(2:9)+j + enddo + write(f71,1000) qa(2:10) +1000 format(b7.7,8b8.8) + write(*,1010) c13,f71 +1010 format('Free text: ',a13/'f71: ',a71) +end program free_text + +subroutine mp_short_ops(w,u) +! Multi-precision arithmetic with storage in character arrays. + character*1 w(*),u(*) + integer i,ireg,j,n,ir,iv,ii1,ii2 + character*1 creg(4) + save ii1,ii2 + equivalence (ireg,creg) + + entry mp_short_init + ireg=256*ichar('2')+ichar('1') + do j=1,4 + if (creg(j).eq.'1') ii1=j + if (creg(j).eq.'2') ii2=j + enddo + return + + entry mp_short_add(w,u,n,iv) + ireg=256*iv + do j=n,1,-1 + ireg=ichar(u(j))+ichar(creg(ii2)) + w(j+1)=creg(ii1) + enddo + w(1)=creg(ii2) + return + + entry mp_short_mult(w,u,n,iv) + ireg=0 + do j=n,1,-1 + ireg=ichar(u(j))*iv+ichar(creg(ii2)) + w(j+1)=creg(ii1) + enddo + w(1)=creg(ii2) + return + + return +end subroutine mp_short_ops diff --git a/lib/77bit/nonstd_to_c58.f90 b/lib/77bit/nonstd_to_c58.f90 new file mode 100644 index 000000000..09190423e --- /dev/null +++ b/lib/77bit/nonstd_to_c58.f90 @@ -0,0 +1,13 @@ +program nonstd_to_c58 + integer*8 n58 + character*11 call_nonstd + character*38 c + data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/'/ + call_nonstd='PJ4/K1ABC' !Redifine as needed + n58=0 + do i=1,11 + n58=n58*38 + index(c,call_nonstd(i:i)) - 1 + enddo + write(*,1000) call_nonstd,n58 +1000 format('Callsign: ',a11,2x,'c58 as decimal integer:',i20) +end program nonstd_to_c58 diff --git a/lib/t6.f90 b/lib/t6.f90 deleted file mode 100644 index fd08f01f4..000000000 --- a/lib/t6.f90 +++ /dev/null @@ -1,56 +0,0 @@ -program t6 - - parameter (MAXFFT=1404) - complex c(0:MAXFFT-1) - real s(0:MAXFFT-1) - - m1=45 - m2=67 - m3=89 - nsym=3*11 + m1 + m2 + m3 - nfft=6*nsym - nh=nfft/2 - - best=9999. -! do m1=22,67 -! do m2=37,97 - do m1=30,67 - do m2=26,100 - m3=201-m2-m1 - if(m3.lt.13) cycle - c=0. - n1=6*(11+m1) - n2=n1+6*(11+m2) - c(1:66)=1. - c(1+n1:66+n1)=1. - c(1+n2:66+n2)=1. - - call four2a(c,nfft,1,-1,1) !c2c FFT - - df=12000.0/nfft - smax=0. - do i=0,nfft-1 - s(i)=real(c(i))**2 + aimag(c(i))**2 - if(i.ne.0) smax=max(s(i),smax) - enddo - sidelobe=db(smax/s(0)) - - if(sidelobe.lt.best) then - write(*,1000) m1,m2,m3,sidelobe -1000 format(3i5,f8.2) - best=sidelobe - s=s/s(0) - rewind 13 - do j=0,nfft-1 - i=mod(j+nh,nfft) - f=i*df - if(i.gt.nh) f=f-12000.0 - write(13,1020) f,s(i) -1020 format(2f12.4) - enddo - endif - enddo - enddo - -end program t6 - From 8a21533c2178a2d5a0057493b53422abd0c4bbd5 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 21 Jun 2020 18:46:21 -0400 Subject: [PATCH 055/239] UPdate some estimates in fst280.txt. --- lib/fst280/fst280.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/fst280/fst280.txt b/lib/fst280/fst280.txt index 5e2c1c935..8c9757e40 100644 --- a/lib/fst280/fst280.txt +++ b/lib/fst280/fst280.txt @@ -1,10 +1,10 @@ ------------------------------------------------------------------- NSPS T/R TxT Tst Txtra Txtra-2.6s DF BW SNR77 SNR50 - (s) (s) (s) (s) (s) (Hz) (Hz) (dB) (dB) + (s) (s) (s) (s) (s) (Hz) (Hz) (dB)? (dB)? ------------------------------------------------------------------- - 800 15 10.93 0.5 3.57 0.97 15.00 60.0 -21.3 -23.2 - 1680 30 22.96 1.0 6.04 3.44 7.14 28.6 -24.5 -26.4 - 4000 60 54.67 1.0 4.33 1.73 3.00 12.0 -28.3 -30.2 - 8400 120 114.80 1.0 4.20 1.60 1.43 5.7 -31.5 -33.4 -21504 300 293.89 1.0 5.11 2.51 0.56 2.2 -35.5 -37.4 + 800 15 10.93 0.5 3.57 0.97 15.00 60.0 -21.3 -22.6 + 1680 30 22.96 1.0 6.04 3.44 7.14 28.6 -24.5 -25.8 + 4000 60 54.67 1.0 4.33 1.73 3.00 12.0 -28.3 -29.6 + 8400 120 114.80 1.0 4.20 1.60 1.43 5.7 -31.5 -32.8 +21504 300 293.89 1.0 5.11 2.51 0.56 2.2 -35.5 -36.8 ------------------------------------------------------------------- From 7d5fb03dea8b4c79f10f2f5f3da120244a78a313 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 22 Jun 2020 08:11:45 -0500 Subject: [PATCH 056/239] First cut at SNR estimate. Needs testing. --- lib/fst280/get_fst280_bitmetrics.f90 | 2 +- lib/fst280_decode.f90 | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst280/get_fst280_bitmetrics.f90 index f9f5f1b7e..598a385fc 100644 --- a/lib/fst280/get_fst280_bitmetrics.f90 +++ b/lib/fst280/get_fst280_bitmetrics.f90 @@ -1,4 +1,4 @@ -subroutine get_fst280_bitmetrics(cd,nss,hmod,nmax,bitmetrics,badsync) +subroutine get_fst280_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) include 'fst280_params.f90' complex cd(0:NN*nss-1) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 0d10eb095..141bd35b8 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -44,6 +44,8 @@ contains real llr(280),llra(280),llrb(280),llrc(280),llrd(280) real candidates(100,4) real bitmetrics(328,4) + real s4(0:3,NN) + integer itone(NN) integer hmod integer*1 apmask(280),cw(280) integer*1 hbits(328) @@ -133,7 +135,7 @@ contains ! Get first approximation of candidate frequencies call get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates) + ncand,candidates,base) ndecodes=0 decodes=' ' @@ -249,10 +251,8 @@ contains is0=isbest+ioffset if(is0.lt.0) cycle cframe=c2(is0:is0+164*nss-1) - s2=sum(cframe*conjg(cframe)) - cframe=cframe/sqrt(s2) bitmetrics=0 - call get_fst280_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,badsync) + call get_fst280_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,s4,badsync) if(badsync) cycle hbits=0 @@ -319,6 +319,20 @@ contains if(idupe.eq.1) exit ndecodes=ndecodes+1 decodes(ndecodes)=msg + if(iwspr.eq.0) then + call get_fst280_tones_from_bits(message101,itone,iwspr) + xsig=0 + do i=1,NN + xsig=xsig+s4(itone(i),i)**2 + enddo + arg=400.0*(xsig/base)-1.0 + if(arg.gt.0.0) then + xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) + else + xsnr=-99.9 + endif +!write(*,*) xsig,base,arg,xsnr + endif nsnr=nint(xsnr) iaptype=0 qual=0. @@ -433,7 +447,7 @@ contains end subroutine fst280_downsample subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates) + ncand,candidates,base) complex c_bigfft(0:nfft1/2) integer hmod From 963bd78f63866f4d92dc3bf7991ac14e0df80248 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 22 Jun 2020 09:46:48 -0500 Subject: [PATCH 057/239] Tweak for better sensitivity. --- lib/fst280_decode.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 141bd35b8..8896af544 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -264,7 +264,7 @@ contains ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 - if(nsync_qual.lt. 30) cycle !### Value ?? ### + if(nsync_qual.lt. 28) cycle !### Value ?? ### scalefac=2.83 llra( 1:140)=bitmetrics( 17:156, 1) @@ -482,7 +482,7 @@ contains call pctile(s2(ia:ib),ib-ia+1,30,base) s2=s2/base - thresh=1.4 + thresh=1.30 ncand=0 candidates=0 From 65996b015c4d3b028dc0e7f61909a96629982d6b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 22 Jun 2020 15:20:02 -0400 Subject: [PATCH 058/239] Exten the DT search range, Steve's suggestion. --- lib/fst280_decode.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 8896af544..a5b84d681 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -159,7 +159,7 @@ contains do isync=0,1 if(isync.eq.0) then fc1=0.0 - is0=nint(fs2) + is0=2*nint(fs2) ishw=is0 isst=4 ifhw=10 From 04e326e75a1b99742bbc54cace5d0bf54437965d Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 22 Jun 2020 15:20:41 -0400 Subject: [PATCH 059/239] Change "Enable VHF/UHF/Microwave features" to "Enable VHF and submode features", and remove the popup warning about being on a lower band. --- Configuration.ui | 6 +++--- widgets/mainwindow.cpp | 16 ---------------- widgets/mainwindow.h | 2 -- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/Configuration.ui b/Configuration.ui index fa16476e9..44a57af24 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -357,7 +357,7 @@ - Enable VHF/UHF/Microwave features + Enable VHF and submode features @@ -3110,11 +3110,11 @@ Right click for insert and delete options. - + + - diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 750e40520..6b17d8e24 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -959,7 +959,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_bFastDone=false; m_bAltV=false; m_bNoMoreFiles=false; - m_bVHFwarned=false; m_bDoubleClicked=false; m_bCallingCQ=false; m_bCheckedContest=false; @@ -4082,11 +4081,6 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { // qDebug() << "onesec" << m_mode; - if(m_freqNominal!=0 and m_freqNominal<50000000 and m_config.enable_VHF_features()) { - if(!m_bVHFwarned) vhfWarning(); - } else { - m_bVHFwarned=false; - } m_currentBand=m_config.bands()->find(m_freqNominal); if( SpecOp::HOUND == m_config.special_op_id() ) { @@ -6436,7 +6430,6 @@ void MainWindow::switch_mode (Mode mode) ui->RxFreqSpinBox->setMaximum(5000); ui->RxFreqSpinBox->setSingleStep(1); } - m_bVHFwarned=false; bool b=m_mode=="FreqCal"; ui->tabWidget->setVisible(!b); if(b) { @@ -6671,20 +6664,11 @@ void MainWindow::band_changed (Frequency f) { m_frequency_list_fcal_iter = m_config.frequencies ()->find (f); } - float r=m_freqNominal/(f+0.0001); - if(r<0.9 or r>1.1) m_bVHFwarned=false; setRig (f); setXIT (ui->TxFreqSpinBox->value ()); } } -void MainWindow::vhfWarning() -{ - MessageBox::warning_message (this, tr ("VHF features warning"), - "VHF/UHF/Microwave features is enabled on a lower frequency band."); - m_bVHFwarned=true; -} - void MainWindow::enable_DXCC_entity (bool on) { if (on and !m_mode.startsWith ("WSPR") and m_mode!="Echo") { diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index ac8c22d15..51a935c93 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -677,7 +677,6 @@ private: bool m_tx_watchdog; // true when watchdog triggered bool m_block_pwr_tooltip; bool m_PwrBandSetOK; - bool m_bVHFwarned; bool m_bDisplayedOnce; Frequency m_lastMonitoredFrequency; double m_toneSpacing; @@ -762,7 +761,6 @@ private: void tx_watchdog (bool triggered); qint64 nWidgets(QString t); void displayWidgets(qint64 n); - void vhfWarning(); QChar current_submode () const; // returns QChar {0} if submode is not appropriate void write_transmit_entry (QString const& file_name); void selectHound(QString t); From 9741e08af2fbd0a28df840315b22a13afa7b32a1 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 22 Jun 2020 14:51:01 -0500 Subject: [PATCH 060/239] Improve sync search range to account for hmod>1. --- lib/fst280_decode.f90 | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 8896af544..27eccafb3 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -146,7 +146,7 @@ contains fc28=0. do icand=1,ncand fc0=candidates(icand,1) - xsnr=candidates(icand,2) + detmet=candidates(icand,2) ! Downconvert and downsample a slice of the spectrum centered on the ! rough estimate of the candidates frequency. @@ -161,16 +161,16 @@ contains fc1=0.0 is0=nint(fs2) ishw=is0 - isst=4 - ifhw=10 - df=.1*8400/nsps + isst=4*hmod + ifhw=12 + df=.1*baud else if(isync.eq.1) then fc1=fc28 is0=isbest8 - ishw=4 - isst=1 - ifhw=10 - df=.02*8400/nsps + ishw=4*hmod + isst=1*hmod + ifhw=7 + df=.02*baud endif smax1=0.0 @@ -211,7 +211,6 @@ contains candidates(icand,3)=fc_synced candidates(icand,4)=isbest enddo - ! remove duplicate candidates do icand=1,ncand fc=candidates(icand,3) @@ -264,8 +263,7 @@ contains ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 - if(nsync_qual.lt. 28) cycle !### Value ?? ### - + if(nsync_qual.lt. 26) cycle !### Value ?? ### scalefac=2.83 llra( 1:140)=bitmetrics( 17:156, 1) llra(141:280)=bitmetrics(173:312, 1) @@ -481,7 +479,6 @@ contains enddo call pctile(s2(ia:ib),ib-ia+1,30,base) s2=s2/base - thresh=1.30 ncand=0 @@ -494,11 +491,7 @@ contains (s2(i).gt.thresh).and.ncand.lt.100) then ncand=ncand+1 candidates(ncand,1)=df2*i - x=s2(i)-1 - snr=-99 -! temporary placeholder until we implement subtraction... - if(x.gt.0) snr=10*log10(x)-10*log10(2500.0*nsps/12000.0)+6.0 - candidates(ncand,2)=snr + candidates(ncand,2)=s2(i) endif enddo From 67f2450cc5d4d053ead1cd905e6126f4b378a995 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 22 Jun 2020 15:21:55 -0500 Subject: [PATCH 061/239] Make noise analysis bandwidth at least 10 times the signal bandwidth, when possible. --- lib/fst280_decode.f90 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 98c8cd191..876caf316 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -464,20 +464,31 @@ contains df2=baud/2.0 nd=df2/df1 ndh=nd/2 - ia=fa/df2 - ib=fb/df2 + ia=nint(max(100.0,fa)/df2) + ib=nint(min(4800.0,fb)/df2) + signal_bw=4*(12000.0/nsps)*hmod + analysis_bw=min(4800.0,fb)-max(100.0,fa) + noise_bw=10.0*signal_bw + if(analysis_bw.gt.noise_bw) then + ina=ia + inb=ib + else + fcenter=(fa+fb)/2.0 + ina=nint(max(100.0,fcenter-noise_bw/2.)/df2) + inb=nint(min(4800.0,fcenter+noise_bw/2.)/df2) + endif s=0. - do i=ia,ib + do i=ina,inb ! noise analysis window includes signal analysis window j0=nint(i*df2/df1) do j=j0-ndh,j0+ndh s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo nh=hmod - do i=ia,ib + do i=ina,inb s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) enddo - call pctile(s2(ia:ib),ib-ia+1,30,base) + call pctile(s2(ina:inb),ib-ia+1,30,base) s2=s2/base thresh=1.30 From 1b2d690bf030ac20c38e945b21eee3b1a4f06845 Mon Sep 17 00:00:00 2001 From: K9AN Date: Tue, 23 Jun 2020 09:45:44 -0500 Subject: [PATCH 062/239] Avoid edge effects when finding noise baseline. --- lib/fst280_decode.f90 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 876caf316..4f3166afa 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -60,7 +60,6 @@ contains iwspr=0 nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 - if(ntrperiod.eq.15) then nsps=800 nmax=15*12000 @@ -236,10 +235,9 @@ contains endif enddo ncand=ic - do icand=1,ncand fc_synced=candidates(icand,3) - isbest=nint(candidates(icand,4)) + isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) @@ -474,8 +472,10 @@ contains inb=ib else fcenter=(fa+fb)/2.0 - ina=nint(max(100.0,fcenter-noise_bw/2.)/df2) - inb=nint(min(4800.0,fcenter+noise_bw/2.)/df2) + fl = max(100.0,fcenter-noise_bw/2.)/df2 + fh = min(4800.0,fcenter+noise_bw/2.)/df2 + ina=nint(fl) + inb=nint(fh) endif s=0. do i=ina,inb ! noise analysis window includes signal analysis window @@ -484,14 +484,13 @@ contains s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo - nh=hmod do i=ina,inb - s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) + s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) enddo - call pctile(s2(ina:inb),ib-ia+1,30,base) + call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) s2=s2/base thresh=1.30 - + ncand=0 candidates=0 if(ia.lt.3) ia=3 From b006d8381a8c5ab2574405275a690147c0f386e6 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 23 Jun 2020 14:21:25 -0400 Subject: [PATCH 063/239] Code for a C++ puzzle. --- widgets/mainwindow.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6b17d8e24..ea7f54a10 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4081,6 +4081,20 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { // qDebug() << "onesec" << m_mode; + +/* +{ + qint64 m_silentFrames; + unsigned mstr=3000; //Also try 1000 and 3000 + unsigned delay_ms=1000; + unsigned m_ic=0; + unsigned m_frameRate=48000; + m_silentFrames = m_ic + (delay_ms-mstr)*m_frameRate/1000; +// m_silentFrames = m_ic + 0.001*(delay_ms-mstr)*m_frameRate; + qDebug() << m_silentFrames; +} +*/ + m_currentBand=m_config.bands()->find(m_freqNominal); if( SpecOp::HOUND == m_config.special_op_id() ) { From 344b9c11f325c4bf73c038008163d90484c780d9 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 23 Jun 2020 15:08:56 -0400 Subject: [PATCH 064/239] Speed up gen_fst280wave() by nearly x10 for longest FST280 transmissions. --- lib/fst280/gen_fst280wave.f90 | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index 9245af406..8485b99d8 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -1,21 +1,31 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & icmplx,cwave,wave) + parameter(NTAB=65536) real wave(nwave) - complex cwave(nwave) + complex cwave(nwave),ctab(0:NTAB-1) real, allocatable, save :: pulse(:) real, allocatable :: dphi(:) integer hmod integer itone(nsym) +! integer*8 count0,count1,clkfreq logical first data first/.true./ data nsps0/-99/ - save first,twopi,dt,tsym,nsps0 + save first,twopi,dt,tsym,nsps0,ctab + +! call system_clock(count0,clkfreq) + if(first) then + twopi=8.0*atan(1.0) + do i=0,NTAB-1 + phi=i*twopi/NTAB + ctab(i)=cmplx(cos(phi),sin(phi)) + enddo + endif if(first.or.nsps.ne.nsps0) then if(allocated(pulse)) deallocate(pulse) allocate(pulse(1:3*nsps)) - twopi=8.0*atan(1.0) dt=1.0/fsample tsym=nsps/fsample ! Compute the smoothed frequency-deviation pulse @@ -46,12 +56,15 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & k=0 do j=0,(nsym+2)*nsps-1 k=k+1 + i=phi*float(NTAB)/twopi + i=iand(i,NTAB-1) if(icmplx.eq.0) then - wave(k)=sin(phi) + wave(k)=real(ctab(i)) else - cwave(k)=cmplx(cos(phi),sin(phi)) + cwave(k)=ctab(i) endif - phi=mod(phi+dphi(j),twopi) + phi=phi+dphi(j) + if(phi.gt.twopi) phi=phi-twopi enddo ! Compute the ramp-up and ramp-down symbols @@ -73,5 +86,10 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 endif +! call system_clock(count1,clkfreq) +! tt=float(count1-count0)/float(clkfreq) +! write(*,3001) tt +!3001 format('Tgen:',f8.3) + return end subroutine gen_fst280wave From 503c2cc24257917f22e62c825b4397270197f860 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 23 Jun 2020 15:10:29 -0400 Subject: [PATCH 065/239] Tweak Modulator to align FST280 Tx start times properly. Still a possible issue with 5-min sequences? --- Modulator/Modulator.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index e527ce3e1..6442fd4d9 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -69,8 +69,13 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, m_bFastMode=fastMode; m_TRperiod=TRperiod; unsigned delay_ms=1000; - if(m_nsps==1920) delay_ms=500; //FT8 - if(m_nsps==576) delay_ms=300; //FT4 + if(m_nsps==1920) delay_ms=500; //FT8 + if(m_nsps==576) delay_ms=300; //FT4 + if(m_nsps==800) delay_ms=750; //FST280-15 + if(m_nsps==1680) delay_ms=650; //FST280-30 + if(m_nsps==4000) delay_ms=450; //FST280-60 + if(m_nsps==8400) delay_ms=250; //FST280-120 + if(m_nsps==21504) delay_ms=50; //FST280-300 // noise generator parameters if (m_addNoise) { @@ -79,22 +84,22 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, if (m_snr > 1.0) m_fac = 3000.0 / m_snr; } + m_ic=0; // round up to an exact portion of a second that allows for startup delays - m_ic = (mstr / delay_ms) * m_frameRate * delay_ms / 1000; - - if(m_bFastMode) m_ic=0; + if(delay_ms > 0 and !m_bFastMode) { + m_ic = (mstr/delay_ms) * m_frameRate * delay_ms / 1000; + } + if(m_nsps==21504) m_ic=int(0.8*48000); //FST280-300 m_silentFrames = 0; // calculate number of silent frames to send, so that audio will start at // the nominal time "delay_ms" into the Tx sequence. if (synchronize && !m_tuning && !m_bFastMode) { - m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000)); + if(delay_ms >= mstr) m_silentFrames = m_ic + 0.001*(delay_ms-mstr)*m_frameRate; } // qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") -// << m_ic << m_silentFrames << m_silentFrames/48000.0 -// << mstr << fmod(double(ms0),1000.0*m_period); - +// << delay_ms << mstr << m_silentFrames << m_ic; initialize (QIODevice::ReadOnly, channel); Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? @@ -152,7 +157,8 @@ qint64 Modulator::readData (char * data, qint64 maxSize) qint16 * end (samples + numFrames * (bytesPerFrame () / sizeof (qint16))); qint64 framesGenerated (0); -// if(m_ic==0) qDebug() << "Modulator::readData" << 0.001*(QDateTime::currentMSecsSinceEpoch() % (1000*m_TRperiod)); +// if(m_ic==0) qDebug() << "aa" << 0.001*(QDateTime::currentMSecsSinceEpoch() % qint64(1000*m_TRperiod)) +// << m_state << m_TRperiod << m_silentFrames << m_ic << foxcom_.wave[m_ic]; switch (m_state) { From 55115a295555409d84e7b210b52b4effd44092c0 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 23 Jun 2020 15:15:45 -0400 Subject: [PATCH 066/239] Move the Wide Graph's green bar for FTol up 3 pixels. --- widgets/plotter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index c25ba6306..947f6a0e5 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -534,7 +534,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_mode=="FST280") { x1=XfromFreq(m_rxFreq-m_tol); x2=XfromFreq(m_rxFreq+m_tol); - painter0.drawLine(x1,29,x2,29); // Mark the Tol range + painter0.drawLine(x1,26,x2,26); // Mark the Tol range } } From 31f98b94b90ba0561446e011c5ce43cef57166bb Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 24 Jun 2020 12:22:22 -0500 Subject: [PATCH 067/239] Make DT search range -1s to +2s. --- lib/fst280_decode.f90 | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 4f3166afa..b05b56894 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -158,14 +158,16 @@ contains do isync=0,1 if(isync.eq.0) then fc1=0.0 - is0=2*nint(fs2) - ishw=is0 + is0=1.5*nint(fs2) + ishw=1.5*is0 isst=4*hmod ifhw=12 df=.1*baud else if(isync.eq.1) then - fc1=fc28 - is0=isbest8 + fc1=fc21 + if(hmod.eq.1) fc1=fc28 + is0=isbest1 + if(hmod.eq.1) is0=isbest8 ishw=4*hmod isst=1*hmod ifhw=7 @@ -408,9 +410,15 @@ contains nsec=8/ncoh do i=1,nsec is=(i-1)*ncoh*nss - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z1=0 + if(i1+is.ge.1) then + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + endif z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z3=0 + if(i3+is+ncoh*nss-1.le.np) then + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + endif s1=s1+abs(z1)/(8*nss) s2=s2+abs(z2)/(8*nss) s3=s3+abs(z3)/(8*nss) From f06f5d77a58005de10178faf13fd94894b3e7eae Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 24 Jun 2020 15:15:20 -0500 Subject: [PATCH 068/239] New frame format, new symbol lengths and ndown values, gen_fst280wave now returns a waveform aligned so that first message symbol starts at t=1s. --- lib/fst280/fst280sim.f90 | 8 ++-- lib/fst280/gen_fst280wave.f90 | 3 ++ lib/fst280/genfst280.f90 | 14 +++++-- lib/fst280_decode.f90 | 72 ++++++++++++++++++++++++----------- 4 files changed, 66 insertions(+), 31 deletions(-) diff --git a/lib/fst280/fst280sim.f90 b/lib/fst280/fst280sim.f90 index 7c29d4298..a11bcc7e4 100644 --- a/lib/fst280/fst280sim.f90 +++ b/lib/fst280/fst280sim.f90 @@ -49,9 +49,9 @@ program fst280sim nsps=0 if(nsec.eq.15) nsps=800 if(nsec.eq.30) nsps=1680 - if(nsec.eq.60) nsps=4000 - if(nsec.eq.120) nsps=8400 - if(nsec.eq.300) nsps=21504 + if(nsec.eq.60) nsps=3888 + if(nsec.eq.120) nsps=8200 + if(nsec.eq.300) nsps=21168 if(nsps.eq.0) then print*,'Invalid TR sequence length.' go to 999 @@ -99,7 +99,7 @@ program fst280sim icmplx=1 f0=f00+1.5*hmod*baud call gen_fst280wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) - k=nint((xdt+1.0)/dt)-nsps + k=nint(xdt/dt) c0=cshift(c0,-k) if(k.gt.0) c0(0:k-1)=0.0 if(k.lt.0) c0(nmax+k:nmax-1)=0.0 diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst280/gen_fst280wave.f90 index 8485b99d8..7a27ca90c 100644 --- a/lib/fst280/gen_fst280wave.f90 +++ b/lib/fst280/gen_fst280wave.f90 @@ -68,6 +68,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & enddo ! Compute the ramp-up and ramp-down symbols + kshift=nsps-nint(fsample) if(icmplx.eq.0) then wave(1:nsps/2)=0.0 wave(nsps/2+1:nsps)=wave(nsps/2+1:nsps) * & @@ -76,6 +77,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & wave(k1+nsps/2:)=0.0 wave(k1:k1+nsps/2-1)=wave(k1:k1+nsps/2-1) * & (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + wave=cshift(wave,kshift) else cwave(1:nsps/2)=0.0 cwave(nsps/2+1:nsps)=cwave(nsps/2+1:nsps) * & @@ -84,6 +86,7 @@ subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & cwave(k1+nsps/2:)=0.0 cwave(k1:k1+nsps/2-1)=cwave(k1:k1+nsps/2-1) * & (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 + cwave=cshift(cwave,kshift) endif ! call system_clock(count1,clkfreq) diff --git a/lib/fst280/genfst280.f90 b/lib/fst280/genfst280.f90 index a0adf5611..919dd2197 100644 --- a/lib/fst280/genfst280.f90 +++ b/lib/fst280/genfst280.f90 @@ -92,11 +92,17 @@ subroutine genfst280(msg0,ichk,msgsent,msgbits,i4tone,iwspr) if(is.eq.3) itmp(i)=2 enddo - i4tone(1:8)=isyncword - i4tone(9:78)=itmp(1:70) + i4tone(1:7)=itmp(1:7) + i4tone(8:14)=itmp(15:21) + i4tone(15:35)=itmp(29:49) + i4tone(36:43)=isyncword + i4tone(44:78)=itmp(50:84) i4tone(79:86)=isyncword - i4tone(87:156)=itmp(71:140) - i4tone(157:164)=isyncword + i4tone(87:121)=itmp(85:119) + i4tone(122:129)=isyncword + i4tone(130:150)=itmp(120:140) + i4tone(151:157)=itmp(22:28) + i4tone(158:164)=itmp(8:14) 999 return diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index b05b56894..622b241e0 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -72,18 +72,19 @@ contains if(hmod.eq.4) ndown=10 if(hmod.eq.8) ndown=5 else if(ntrperiod.eq.60) then - nsps=4000 + nsps=3888 nmax=60*12000 - ndown=100/hmod - if(hmod.eq.8) ndown=16 + ndown=96/hmod + if(hmod.eq.1) ndown=108 else if(ntrperiod.eq.120) then - nsps=8400 + nsps=8200 nmax=120*12000 - ndown=200/hmod + if(hmod.eq.1) ndown=205 + ndown=100/hmod else if(ntrperiod.eq.300) then - nsps=21504 + nsps=21168 nmax=300*12000 - ndown=512/hmod + ndown=504/hmod end if nss=nsps/ndown fs=12000.0 !Sample rate @@ -239,7 +240,7 @@ contains ncand=ic do icand=1,ncand fc_synced=candidates(icand,3) - isbest=nint(candidates(icand,4)) + isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) @@ -256,26 +257,51 @@ contains hbits=0 where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) - ns2=count(hbits( 9: 16).eq.(/0,1,0,0,1,1,1,0/)) + ns1=count(hbits( 71: 78).eq.(/0,0,0,1,1,0,1,1/)) + ns2=count(hbits( 79: 86).eq.(/0,1,0,0,1,1,1,0/)) ns3=count(hbits(157:164).eq.(/0,0,0,1,1,0,1,1/)) ns4=count(hbits(165:172).eq.(/0,1,0,0,1,1,1,0/)) - ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) - ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) + ns5=count(hbits(243:250).eq.(/0,0,0,1,1,0,1,1/)) + ns6=count(hbits(251:258).eq.(/0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 if(nsync_qual.lt. 26) cycle !### Value ?? ### + scalefac=2.83 - llra( 1:140)=bitmetrics( 17:156, 1) - llra(141:280)=bitmetrics(173:312, 1) + llra( 1: 14)=bitmetrics( 1: 14, 1) + llra( 15: 28)=bitmetrics(315:328, 1) + llra( 29: 42)=bitmetrics( 15: 28, 1) + llra( 43: 56)=bitmetrics(301:314, 1) + llra( 57: 98)=bitmetrics( 29: 70, 1) + llra( 99:168)=bitmetrics( 87:156, 1) + llra(169:238)=bitmetrics(173:242, 1) + llra(239:280)=bitmetrics(259:300, 1) llra=scalefac*llra - llrb( 1:140)=bitmetrics( 17:156, 2) - llrb(141:280)=bitmetrics(173:312, 2) + llrb( 1: 14)=bitmetrics( 1: 14, 2) + llrb( 15: 28)=bitmetrics(315:328, 2) + llrb( 29: 42)=bitmetrics( 15: 28, 2) + llrb( 43: 56)=bitmetrics(301:314, 2) + llrb( 57: 98)=bitmetrics( 29: 70, 2) + llrb( 99:168)=bitmetrics( 87:156, 2) + llrb(169:238)=bitmetrics(173:242, 2) + llrb(239:280)=bitmetrics(259:300, 2) llrb=scalefac*llrb - llrc( 1:140)=bitmetrics( 17:156, 3) - llrc(141:280)=bitmetrics(173:312, 3) + llrc( 1: 14)=bitmetrics( 1: 14, 3) + llrc( 15: 28)=bitmetrics(315:328, 3) + llrc( 29: 42)=bitmetrics( 15: 28, 3) + llrc( 43: 56)=bitmetrics(301:314, 3) + llrc( 57: 98)=bitmetrics( 29: 70, 3) + llrc( 99:168)=bitmetrics( 87:156, 3) + llrc(169:238)=bitmetrics(173:242, 3) + llrc(239:280)=bitmetrics(259:300, 3) llrc=scalefac*llrc - llrd( 1:140)=bitmetrics( 17:156, 4) - llrd(141:280)=bitmetrics(173:312, 4) + llrd( 1: 14)=bitmetrics( 1: 14, 4) + llrd( 15: 28)=bitmetrics(315:328, 4) + llrd( 29: 42)=bitmetrics( 15: 28, 4) + llrd( 43: 56)=bitmetrics(301:314, 4) + llrd( 57: 98)=bitmetrics( 29: 70, 4) + llrd( 99:168)=bitmetrics( 87:156, 4) + llrd(169:238)=bitmetrics(173:242, 4) + llrd(239:280)=bitmetrics(259:300, 4) llrd=scalefac*llrd apmask=0 @@ -329,7 +355,7 @@ contains else xsnr=-99.9 endif -!write(*,*) xsig,base,arg,xsnr +!write(*,*) xsig,base,arg,xsnr,nsync_qual,ntype,nharderrors,dmin,msg endif nsnr=nint(xsnr) iaptype=0 @@ -400,9 +426,9 @@ contains f0save=f0 endif - i1=i0 !Costas arrays + i1=i0+35*nss !Costas arrays i2=i0+78*nss - i3=i0+156*nss + i3=i0+121*nss s1=0.0 s2=0.0 From 1226aacaadbe3458391acbd8b8497f38d968b029 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 24 Jun 2020 21:25:02 -0400 Subject: [PATCH 069/239] Remove the silly C++ puzzle, no longer needed. --- widgets/mainwindow.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ea7f54a10..84eab0715 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4081,22 +4081,7 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { // qDebug() << "onesec" << m_mode; - -/* -{ - qint64 m_silentFrames; - unsigned mstr=3000; //Also try 1000 and 3000 - unsigned delay_ms=1000; - unsigned m_ic=0; - unsigned m_frameRate=48000; - m_silentFrames = m_ic + (delay_ms-mstr)*m_frameRate/1000; -// m_silentFrames = m_ic + 0.001*(delay_ms-mstr)*m_frameRate; - qDebug() << m_silentFrames; -} -*/ - m_currentBand=m_config.bands()->find(m_freqNominal); - if( SpecOp::HOUND == m_config.special_op_id() ) { qint32 tHound=QDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn; //To keep calling Fox, Hound must reactivate Enable Tx at least once every 2 minutes From 76e84ec8fa1cfa3cd499ec1cc2cfe63577201519 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 25 Jun 2020 08:54:16 -0500 Subject: [PATCH 070/239] Add debug print statement, lower sync threshold. --- lib/fst280_decode.f90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 622b241e0..3bf470c14 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -239,6 +239,7 @@ contains enddo ncand=ic do icand=1,ncand + sync=candidates(icand,2) fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 @@ -355,12 +356,13 @@ contains else xsnr=-99.9 endif -!write(*,*) xsig,base,arg,xsnr,nsync_qual,ntype,nharderrors,dmin,msg endif nsnr=nint(xsnr) iaptype=0 qual=0. fsig=fc_synced - 1.5*hmod*baud +!write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & +! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod) goto 2002 @@ -523,7 +525,7 @@ contains enddo call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) s2=s2/base - thresh=1.30 + thresh=1.25 ncand=0 candidates=0 From 9caf3b650cc0e764a998d92ad1d8a7fd4b976220 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 25 Jun 2020 17:18:48 -0400 Subject: [PATCH 071/239] Correct a number of parameters that control FST280 signal duration and timing. --- Modulator/Modulator.cpp | 27 +++++++++++++++++--------- widgets/mainwindow.cpp | 42 ++++++++++++++++++++++++----------------- widgets/mainwindow.h | 2 +- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index 6442fd4d9..3a33c42f1 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -69,13 +69,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, m_bFastMode=fastMode; m_TRperiod=TRperiod; unsigned delay_ms=1000; - if(m_nsps==1920) delay_ms=500; //FT8 - if(m_nsps==576) delay_ms=300; //FT4 - if(m_nsps==800) delay_ms=750; //FST280-15 - if(m_nsps==1680) delay_ms=650; //FST280-30 - if(m_nsps==4000) delay_ms=450; //FST280-60 - if(m_nsps==8400) delay_ms=250; //FST280-120 - if(m_nsps==21504) delay_ms=50; //FST280-300 + if(m_nsps==1920) delay_ms=500; //FT8 + if(m_nsps==576) delay_ms=300; //FT4 // noise generator parameters if (m_addNoise) { @@ -89,7 +84,6 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, if(delay_ms > 0 and !m_bFastMode) { m_ic = (mstr/delay_ms) * m_frameRate * delay_ms / 1000; } - if(m_nsps==21504) m_ic=int(0.8*48000); //FST280-300 m_silentFrames = 0; // calculate number of silent frames to send, so that audio will start at @@ -98,9 +92,21 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, if(delay_ms >= mstr) m_silentFrames = m_ic + 0.001*(delay_ms-mstr)*m_frameRate; } -// qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") + // Special case for FST280: +// qDebug() << "aa" << m_ic << m_silentFrames << m_symbolsLength << m_nsps; + if(m_nsps==800 or m_nsps==1680 or m_nsps==3888 or m_nsps==8200 or m_nsps==21168) { + m_ic = m_ic + 48000 - 2*m_nsps + 9600; //The 9600 is empirical + m_silentFrames = m_silentFrames - 2*m_nsps; + } + if(m_silentFrames<0) { + m_ic = m_ic - m_silentFrames; + m_silentFrames = 0; + } +// qDebug() << "bb" << m_ic << m_silentFrames; +// qDebug() << "cc" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") // << delay_ms << mstr << m_silentFrames << m_ic; + initialize (QIODevice::ReadOnly, channel); Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? Synchronizing : Active)); @@ -317,6 +323,9 @@ qint64 Modulator::readData (char * data, qint64 maxSize) ++m_ic; } +// qDebug() << "dd" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") +// << m_ic << m_amp << foxcom_.wave[m_ic]; + if (m_amp == 0.0) { // TODO G4WJS: compare double with zero might not be wise if (icw[0] == 0) { // no CW ID to send diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 84eab0715..4ac9f485c 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1342,11 +1342,18 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST280" or m_mode=="FST280W") { - if(m_TRperiod==15) m_hsymStop=51; - if(m_TRperiod==30) m_hsymStop=95; - if(m_TRperiod==60) m_hsymStop=205; - if(m_TRperiod==120) m_hsymStop=414; - if(m_TRperiod==300) m_hsymStop=1036; + int stop[] = {45,87,192,397,1012}; + int stop_EME[] = {51,96,201,406,1021}; + int i=0; + if(m_TRperiod==30) i=1; + if(m_TRperiod==60) i=2; + if(m_TRperiod==120) i=3; + if(m_TRperiod==300) i=4; + if(m_config.decode_at_52s()) { + m_hsymStop=stop_EME[i]; + } else { + m_hsymStop=stop[i]; + } } } @@ -3531,11 +3538,11 @@ void MainWindow::guiUpdate() if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR if(m_modeTx=="FST280" or m_mode=="FST280W") { //FST280, FST280W - if(m_TRperiod==15) txDuration=1.0 + 164*800/12000.0; - if(m_TRperiod==30) txDuration=1.0 + 164*1680/12000.0; - if(m_TRperiod==60) txDuration=1.0 + 164*4000/12000.0; - if(m_TRperiod==120) txDuration=1.0 + 164*8400/12000.0; - if(m_TRperiod==300) txDuration=1.0 + 164*2150500/12000.0; + if(m_TRperiod==15) txDuration=1.0 + 166*800/12000.0; + if(m_TRperiod==30) txDuration=1.0 + 166*1680/12000.0; + if(m_TRperiod==60) txDuration=1.0 + 166*3888/12000.0; + if(m_TRperiod==120) txDuration=1.0 + 166*8200/12000.0; + if(m_TRperiod==300) txDuration=1.0 + 166*21168/12000.0; } if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 @@ -3877,15 +3884,16 @@ void MainWindow::guiUpdate() int hmod=int(pow(2.0,double(m_nSubMode))); int nsps=800; if(m_TRperiod==30) nsps=1680; - if(m_TRperiod==60) nsps=4000; - if(m_TRperiod==120) nsps=8400; - if(m_TRperiod==300) nsps=21504; + if(m_TRperiod==60) nsps=3888; + if(m_TRperiod==120) nsps=8200; + if(m_TRperiod==300) nsps=21168; nsps=4*nsps; //48000 Hz sampling int nsym=164; float fsample=48000.0; float dfreq=hmod*fsample/nsps; float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; - int nwave=(nsym+2)*nsps; +// int nwave=(nsym+2)*nsps; + int nwave=48000 + 166*nsps; int icmplx=0; gen_fst280wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); @@ -7160,9 +7168,9 @@ void MainWindow::transmit (double snr) toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. int nsps=800; if(m_TRperiod==30) nsps=1680; - if(m_TRperiod==60) nsps=4000; - if(m_TRperiod==120) nsps=8400; - if(m_TRperiod==300) nsps=21504; + if(m_TRperiod==60) nsps=3888; + if(m_TRperiod==120) nsps=8200; + if(m_TRperiod==300) nsps=21168; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 51a935c93..b342850bd 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -49,7 +49,7 @@ #define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync #define NUM_FT8_SYMBOLS 79 #define NUM_FT4_SYMBOLS 105 -#define NUM_FST280_SYMBOLS 164 //280/2 data + 6*4 sync +#define NUM_FST280_SYMBOLS 166 //280/2 data + 6*4 sync + 2 ramp #define NUM_CW_SYMBOLS 250 #define TX_SAMPLE_RATE 48000 #define N_WIDGETS 33 From 37d5af931170970a6746a800bc839d08d25ca190 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 26 Jun 2020 07:24:11 -0500 Subject: [PATCH 072/239] Fix an out-of-bounds error. --- lib/fst280_decode.f90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 3bf470c14..64d2087be 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -520,6 +520,9 @@ contains s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo + if(ina-hmod*3.lt.1) ina=1+hmod*3 + if(inb+hmod*3.gt.18000) inb=18000-hmod*3 + s2=0. do i=ina,inb s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) enddo From 2cfe0513bba9c9173c6f08455f58fb279eb87a03 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 26 Jun 2020 08:40:01 -0500 Subject: [PATCH 073/239] Adjust analysis window when single-decode is checked. --- lib/fst280_decode.f90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/fst280_decode.f90 b/lib/fst280_decode.f90 index 64d2087be..5969146c9 100644 --- a/lib/fst280_decode.f90 +++ b/lib/fst280_decode.f90 @@ -105,8 +105,8 @@ contains npts=nmax if(single_decode) then - fa=max(100,nfqso-ntol) - fb=min(4800,nfqso+ntol) + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) else fa=max(100,nfa) fb=min(4800,nfb) @@ -243,6 +243,7 @@ contains fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 + call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) do ijitter=0,jittermax @@ -520,8 +521,8 @@ contains s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo - if(ina-hmod*3.lt.1) ina=1+hmod*3 - if(inb+hmod*3.gt.18000) inb=18000-hmod*3 + ina=max(ina,1+3*hmod) + inb=min(inb,18000-3*hmod) s2=0. do i=ina,inb s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) From 390884268cac035c2602143267c0572452ac8bd9 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 27 Jun 2020 08:53:11 -0500 Subject: [PATCH 074/239] Wholesale change from FST280 to FST240 --- CMakeLists.txt | 42 +- lib/decoder.f90 | 36 +- lib/fsk4hf/.DS_Store | Bin 0 -> 6148 bytes lib/fst240/bpdecode240_101.f90 | 111 ++++ lib/{fst280 => fst240}/bpdecode280_101.f90 | 0 lib/{fst280 => fst240}/bpdecode280_74.f90 | 0 lib/fst240/decode240_101.f90 | 154 +++++ lib/{fst280 => fst240}/decode280_101.f90 | 0 lib/{fst280 => fst240}/decode280_74.f90 | 0 lib/fst240/encode240_101.f90 | 46 ++ lib/{fst280 => fst240}/encode280_101.f90 | 0 lib/{fst280 => fst240}/encode280_74.f90 | 0 lib/fst240/fst240_params.f90 | 7 + lib/fst240/fst240sim.f90 | 143 +++++ lib/{fst280 => fst240}/fst280.txt | 0 lib/{fst280 => fst240}/fst280_params.f90 | 0 lib/{fst280 => fst240}/fst280d.f90 | 0 lib/{fst280 => fst240}/fst280sim.f90 | 0 lib/fst240/gen_fst240wave.f90 | 98 ++++ lib/{fst280 => fst240}/gen_fst280wave.f90 | 0 lib/fst240/genfst240.f90 | 101 ++++ lib/{fst280 => fst240}/genfst280.f90 | 0 lib/{fst280 => fst240}/get_crc24.f90 | 0 lib/fst240/get_fst240_bitmetrics.f90 | 123 ++++ .../get_fst280_bitmetrics.f90 | 0 lib/fst240/ldpc_240_101_generator.f90 | 142 +++++ lib/fst240/ldpc_240_101_parity.f90 | 393 +++++++++++++ .../ldpc_280_101_generator.f90 | 0 .../ldpc_280_101_parity.f90 | 0 .../ldpc_280_74_generator.f90 | 0 lib/{fst280 => fst240}/ldpc_280_74_parity.f90 | 0 lib/fst240/ldpcsim240_101.f90 | 143 +++++ lib/{fst280 => fst240}/ldpcsim280_101.f90 | 0 lib/{fst280 => fst240}/ldpcsim280_74.f90 | 0 lib/fst240/osd240_101.f90 | 403 +++++++++++++ lib/{fst280 => fst240}/osd280_101.f90 | 0 lib/{fst280 => fst240}/osd280_74.f90 | 0 lib/fst240_decode.f90 | 554 ++++++++++++++++++ lib/jt9.f90 | 8 +- models/FrequencyList.cpp | 28 +- models/Modes.hpp | 4 +- widgets/displaytext.cpp | 2 +- widgets/mainwindow.cpp | 68 +-- widgets/mainwindow.h | 6 +- widgets/mainwindow.ui | 22 +- widgets/plotter.cpp | 8 +- 46 files changed, 2524 insertions(+), 118 deletions(-) create mode 100644 lib/fsk4hf/.DS_Store create mode 100644 lib/fst240/bpdecode240_101.f90 rename lib/{fst280 => fst240}/bpdecode280_101.f90 (100%) rename lib/{fst280 => fst240}/bpdecode280_74.f90 (100%) create mode 100644 lib/fst240/decode240_101.f90 rename lib/{fst280 => fst240}/decode280_101.f90 (100%) rename lib/{fst280 => fst240}/decode280_74.f90 (100%) create mode 100644 lib/fst240/encode240_101.f90 rename lib/{fst280 => fst240}/encode280_101.f90 (100%) rename lib/{fst280 => fst240}/encode280_74.f90 (100%) create mode 100644 lib/fst240/fst240_params.f90 create mode 100644 lib/fst240/fst240sim.f90 rename lib/{fst280 => fst240}/fst280.txt (100%) rename lib/{fst280 => fst240}/fst280_params.f90 (100%) rename lib/{fst280 => fst240}/fst280d.f90 (100%) rename lib/{fst280 => fst240}/fst280sim.f90 (100%) create mode 100644 lib/fst240/gen_fst240wave.f90 rename lib/{fst280 => fst240}/gen_fst280wave.f90 (100%) create mode 100644 lib/fst240/genfst240.f90 rename lib/{fst280 => fst240}/genfst280.f90 (100%) rename lib/{fst280 => fst240}/get_crc24.f90 (100%) create mode 100644 lib/fst240/get_fst240_bitmetrics.f90 rename lib/{fst280 => fst240}/get_fst280_bitmetrics.f90 (100%) create mode 100644 lib/fst240/ldpc_240_101_generator.f90 create mode 100644 lib/fst240/ldpc_240_101_parity.f90 rename lib/{fst280 => fst240}/ldpc_280_101_generator.f90 (100%) rename lib/{fst280 => fst240}/ldpc_280_101_parity.f90 (100%) rename lib/{fst280 => fst240}/ldpc_280_74_generator.f90 (100%) rename lib/{fst280 => fst240}/ldpc_280_74_parity.f90 (100%) create mode 100644 lib/fst240/ldpcsim240_101.f90 rename lib/{fst280 => fst240}/ldpcsim280_101.f90 (100%) rename lib/{fst280 => fst240}/ldpcsim280_74.f90 (100%) create mode 100644 lib/fst240/osd240_101.f90 rename lib/{fst280 => fst240}/osd280_101.f90 (100%) rename lib/{fst280 => fst240}/osd280_74.f90 (100%) create mode 100644 lib/fst240_decode.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index f8986e5c8..20eb32034 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -369,7 +369,7 @@ set (wsjt_FSRCS lib/jt65_mod.f90 lib/ft8_decode.f90 lib/ft4_decode.f90 - lib/fst280_decode.f90 + lib/fst240_decode.f90 lib/jt9_decode.f90 lib/options.f90 lib/packjt.f90 @@ -596,22 +596,16 @@ set (wsjt_FSRCS lib/wqencode.f90 lib/wspr_downsample.f90 lib/zplot9.f90 - lib/fst280/bpdecode280_101.f90 - lib/fst280/bpdecode280_74.f90 - lib/fst280/decode280_101.f90 - lib/fst280/decode280_74.f90 - lib/fst280/encode280_101.f90 - lib/fst280/encode280_74.f90 - lib/fst280/fst280d.f90 - lib/fst280/fst280sim.f90 - lib/fst280/gen_fst280wave.f90 - lib/fst280/genfst280.f90 - lib/fst280/get_fst280_bitmetrics.f90 - lib/fst280/ldpcsim280_101.f90 - lib/fst280/ldpcsim280_74.f90 - lib/fst280/osd280_101.f90 - lib/fst280/osd280_74.f90 - lib/fst280/get_crc24.f90 + lib/fst240/bpdecode240_101.f90 + lib/fst240/decode240_101.f90 + lib/fst240/encode240_101.f90 + lib/fst240/fst240sim.f90 + lib/fst240/gen_fst240wave.f90 + lib/fst240/genfst240.f90 + lib/fst240/get_fst240_bitmetrics.f90 + lib/fst240/ldpcsim240_101.f90 + lib/fst240/osd240_101.f90 + lib/fst240/get_crc24.f90 ) # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit @@ -1368,17 +1362,11 @@ target_link_libraries (ft4sim_mult wsjt_fort wsjt_cxx) add_executable (record_time_signal Audio/tools/record_time_signal.cpp) target_link_libraries (record_time_signal wsjt_cxx wsjt_qtmm wsjt_qt) -add_executable (fst280d lib/fst280/fst280d.f90 wsjtx.rc) -target_link_libraries (fst280d wsjt_fort wsjt_cxx) +add_executable (fst240sim lib/fst240/fst240sim.f90 wsjtx.rc) +target_link_libraries (fst240sim wsjt_fort wsjt_cxx) -add_executable (fst280sim lib/fst280/fst280sim.f90 wsjtx.rc) -target_link_libraries (fst280sim wsjt_fort wsjt_cxx) - -add_executable (ldpcsim280_101 lib/fst280/ldpcsim280_101.f90 wsjtx.rc) -target_link_libraries (ldpcsim280_101 wsjt_fort wsjt_cxx) - -add_executable (ldpcsim280_74 lib/fst280/ldpcsim280_74.f90 wsjtx.rc) -target_link_libraries (ldpcsim280_74 wsjt_fort wsjt_cxx) +add_executable (ldpcsim240_101 lib/fst240/ldpcsim240_101.f90 wsjtx.rc) +target_link_libraries (ldpcsim240_101 wsjt_fort wsjt_cxx) endif(WSJT_BUILD_UTILS) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index b51a3f906..dee9044de 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -8,7 +8,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) use jt9_decode use ft8_decode use ft4_decode - use fst280_decode + use fst240_decode include 'jt9com.f90' include 'timer_common.inc' @@ -33,9 +33,9 @@ subroutine multimode_decoder(ss,id2,params,nfsample) integer :: decoded end type counting_ft4_decoder - type, extends(fst280_decoder) :: counting_fst280_decoder + type, extends(fst240_decoder) :: counting_fst240_decoder integer :: decoded - end type counting_fst280_decoder + end type counting_fst240_decoder real ss(184,NSMAX) logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,ex @@ -53,7 +53,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) type(counting_jt9_decoder) :: my_jt9 type(counting_ft8_decoder) :: my_ft8 type(counting_ft4_decoder) :: my_ft4 - type(counting_fst280_decoder) :: my_fst280 + type(counting_fst240_decoder) :: my_fst240 !cast C character arrays to Fortran character strings datetime=transfer(params%datetime, datetime) @@ -68,7 +68,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) my_jt9%decoded = 0 my_ft8%decoded = 0 my_ft4%decoded = 0 - my_fst280%decoded = 0 + my_fst240%decoded = 0 ! For testing only: return Rx messages stored in a file as decodes inquire(file='rx_messages.txt',exist=ex) @@ -187,14 +187,14 @@ subroutine multimode_decoder(ss,id2,params,nfsample) go to 800 endif - if(params%nmode.eq.280) then -! We're in FST280/FST280W mode - call timer('dec280 ',0) - call my_fst280%decode(fst280_decoded,id2,params%nutc, & + if(params%nmode.eq.240) then +! We're in FST240/FST240W mode + call timer('dec240 ',0) + call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,params%ndepth,params%ntr,params%nexp_decode, & params%ntol) - call timer('dec280 ',1) + call timer('dec240 ',1) go to 800 endif @@ -317,7 +317,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ! JT65 is not yet producing info for nsynced, ndecoded. 800 ndecoded = my_jt4%decoded + my_jt65%decoded + my_jt9%decoded + & - my_ft8%decoded + my_ft4%decoded + my_fst280%decoded + my_ft8%decoded + my_ft4%decoded + my_fst240%decoded if(params%nmode.eq.8 .and. params%nzhsym.eq.41) ndec41=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.47) ndec47=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.50) then @@ -679,13 +679,13 @@ contains return end subroutine ft4_decoded - subroutine fst280_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & + subroutine fst240_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & qual,ntrperiod) - use fst280_decode + use fst240_decode implicit none - class(fst280_decoder), intent(inout) :: this + class(fst240_decoder), intent(inout) :: this integer, intent(in) :: nutc real, intent(in) :: sync integer, intent(in) :: nsnr @@ -709,23 +709,23 @@ contains write(*,1001) nutc,nsnr,dt,nint(freq),decoded0,annot 1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 -1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') +1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') else write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot 1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2) write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 -1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST280') +1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') endif call flush(6) call flush(13) select type(this) - type is (counting_fst280_decoder) + type is (counting_fst240_decoder) this%decoded = this%decoded + 1 end select return - end subroutine fst280_decoded + end subroutine fst240_decoded end subroutine multimode_decoder diff --git a/lib/fsk4hf/.DS_Store b/lib/fsk4hf/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T01: do bp and then call osd maxosd times with saved bp outputs +! norder : osd decoding depth +! + integer, parameter:: N=240, K=101, M=N-K + integer*1 cw(N),apmask(N) + integer*1 nxor(N),hdec(N) + integer*1 message101(101),m101(101) + integer nrw(M),ncw + integer Nm(6,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(6,M) + real tanhtoc(6,M) + real zn(N),zsum(N),zsave(N,3) + real llr(N) + real Tmn + + include "ldpc_240_101_parity.f90" + + maxiterations=30 + nosd=0 + if(maxosd.gt.3) maxosd=3 + if(maxosd.eq.0) then ! osd with channel llrs + nosd=1 + zsave(:,1)=llr + elseif(maxosd.gt.0) then ! + nosd=maxosd + elseif(maxosd.lt.0) then ! just bp + nosd=0 + endif + + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + zsum=0.0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + zsum=zsum+zn + if(iter.gt.0 .and. iter.le.maxosd) then + zsave(:,iter)=zsum + endif + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + m101=0 + m101(1:101)=cw(1:101) + call get_crc24(m101,101,nbadcrc) + if(nbadcrc.eq.0) then + message101=cw(1:101) + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + nharderror=sum(nxor) + dmin=sum(nxor*abs(llr)) + ntype=1 + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + exit + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo ! bp iterations + + do i=1,nosd + zn=zsave(:,i) + call osd240_101(zn,Keff,apmask,norder,message101,cw,nharderror,dminosd) + if(nharderror.gt.0) then + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + dmin=sum(nxor*abs(llr)) + ntype=2 + return + endif + enddo + + ntype=0 + nharderror=-1 + dminosd=0.0 + + return +end subroutine decode240_101 diff --git a/lib/fst280/decode280_101.f90 b/lib/fst240/decode280_101.f90 similarity index 100% rename from lib/fst280/decode280_101.f90 rename to lib/fst240/decode280_101.f90 diff --git a/lib/fst280/decode280_74.f90 b/lib/fst240/decode280_74.f90 similarity index 100% rename from lib/fst280/decode280_74.f90 rename to lib/fst240/decode280_74.f90 diff --git a/lib/fst240/encode240_101.f90 b/lib/fst240/encode240_101.f90 new file mode 100644 index 000000000..da0021df3 --- /dev/null +++ b/lib/fst240/encode240_101.f90 @@ -0,0 +1,46 @@ +subroutine encode240_101(message,codeword) + use, intrinsic :: iso_c_binding + use iso_c_binding, only: c_loc,c_size_t + use crc + + integer, parameter:: N=240, K=101, M=N-K + character*24 c24 + integer*1 codeword(N) + integer*1 gen(M,K) + integer*1 message(K) + integer*1 pchecks(M) + integer*4 ncrc24 + include "ldpc_240_101_generator.f90" + logical first + data first/.true./ + save first,gen + + if( first ) then ! fill the generator matrix + gen=0 + do i=1,M + do j=1,26 + read(g(i)(j:j),"(Z1)") istr + ibmax=4 + if(j.eq.26) ibmax=1 + do jj=1, ibmax + icol=(j-1)*4+jj + if( btest(istr,4-jj) ) gen(i,icol)=1 + enddo + enddo + enddo + first=.false. + endif + + do i=1,M + nsum=0 + do j=1,K + nsum=nsum+message(j)*gen(i,j) + enddo + pchecks(i)=mod(nsum,2) + enddo + + codeword(1:K)=message + codeword(K+1:N)=pchecks + + return +end subroutine encode240_101 diff --git a/lib/fst280/encode280_101.f90 b/lib/fst240/encode280_101.f90 similarity index 100% rename from lib/fst280/encode280_101.f90 rename to lib/fst240/encode280_101.f90 diff --git a/lib/fst280/encode280_74.f90 b/lib/fst240/encode280_74.f90 similarity index 100% rename from lib/fst280/encode280_74.f90 rename to lib/fst240/encode280_74.f90 diff --git a/lib/fst240/fst240_params.f90 b/lib/fst240/fst240_params.f90 new file mode 100644 index 000000000..f6204915d --- /dev/null +++ b/lib/fst240/fst240_params.f90 @@ -0,0 +1,7 @@ +! FST240 +! LDPC(240,101)/CRC24 code, five 8x4 sync + +parameter (KK=77) !Information bits (77 + CRC24) +parameter (ND=120) !Data symbols +parameter (NS=40) !Sync symbols +parameter (NN=NS+ND) !Sync and data symbols (160) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 new file mode 100644 index 000000000..842e32876 --- /dev/null +++ b/lib/fst240/fst240sim.f90 @@ -0,0 +1,143 @@ +program fst240sim + +! Generate simulated signals for experimental slow FT4 mode + + use wavhdr + use packjt77 + include 'fst240_params.f90' !Set various constants + type(hdr) h !Header for .wav file + character arg*12,fname*17 + character msg37*37,msgsent37*37,c77*77 + complex, allocatable :: c0(:) + complex, allocatable :: c(:) + real, allocatable :: wave(:) + integer hmod + integer itone(NN) + integer*1 msgbits(101) + integer*2, allocatable :: iwave(:) !Generated full-length waveform + +! Get command-line argument(s) + nargs=iargc() + if(nargs.ne.9) then + print*,'Need 9 arguments, got ',nargs + print*,'Usage: fst240sim "message" TRsec f0 DT h fdop del nfiles snr' + print*,'Examples: fst240sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15' + go to 999 + endif + call getarg(1,msg37) !Message to be transmitted + call getarg(2,arg) + read(arg,*) nsec !TR sequence length, seconds + call getarg(3,arg) + read(arg,*) f00 !Frequency (only used for single-signal) + call getarg(4,arg) + read(arg,*) xdt !Time offset from nominal (s) + call getarg(5,arg) + read(arg,*) hmod !Modulation index, h + call getarg(6,arg) + read(arg,*) fspread !Watterson frequency spread (Hz) + call getarg(7,arg) + read(arg,*) delay !Watterson delay (ms) + call getarg(8,arg) + read(arg,*) nfiles !Number of files + call getarg(9,arg) + read(arg,*) snrdb !SNR_2500 + + nfiles=abs(nfiles) + twopi=8.0*atan(1.0) + fs=12000.0 !Sample rate (Hz) + dt=1.0/fs !Sample interval (s) + nsps=0 + if(nsec.eq.15) nsps=800 + if(nsec.eq.30) nsps=1680 + if(nsec.eq.60) nsps=3888 + if(nsec.eq.120) nsps=8200 + if(nsec.eq.300) nsps=21168 + if(nsps.eq.0) then + print*,'Invalid TR sequence length.' + go to 999 + endif + baud=12000.0/nsps !Keying rate (baud) + nmax=nsec*12000 + nz=nsps*NN + nz2=nsps*NN2 + txt=nz2*dt !Transmission length (s) + tt=nsps*dt !Duration of symbols (s) + allocate( c0(0:nmax-1) ) + allocate( c(0:nmax-1) ) + allocate( wave(nmax) ) + allocate( iwave(nmax) ) + + bandwidth_ratio=2500.0/(fs/2.0) + sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) + if(snrdb.gt.90.0) sig=1.0 + + i3=-1 + n3=-1 + call pack77(msg37,i3,n3,c77) + call genfst240(msg37,0,msgsent37,msgbits,itone,iwspr) + + write(*,*) + write(*,'(a9,a37)') 'Message: ',msgsent37 + write(*,1000) f00,xdt,hmod,txt,snrdb +1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) + write(*,*) + if(i3.eq.1) then + write(*,*) ' mycall hiscall hisgrid' + write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77) + else + write(*,'(a14)') 'Message bits: ' + write(*,'(50i1,1x,24i1)') msgbits + endif + write(*,*) + write(*,'(a17)') 'Channel symbols: ' + write(*,'(10i1)') itone + write(*,*) + +! call sgran() + + fsample=12000.0 + icmplx=1 + f0=f00+1.5*hmod*baud + call gen_fst240wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) + k=nint(xdt/dt) + c0=cshift(c0,-k) + if(k.gt.0) c0(0:k-1)=0.0 + if(k.lt.0) c0(nmax+k:nmax-1)=0.0 + + do ifile=1,nfiles + c=c0 + if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nmax,NZ,fs,delay,fspread) + c=sig*c + wave=real(c) + if(snrdb.lt.90) then + do i=1,nmax !Add gaussian noise at specified SNR + xnoise=gran() + wave(i)=wave(i) + xnoise + enddo + endif + gain=100.0 + if(snrdb.lt.90.0) then + wave=gain*wave + else + datpk=maxval(abs(wave)) + fac=32766.9/datpk + wave=fac*wave + endif + if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." + iwave=nint(wave) + h=default_header(12000,nmax) + if(nmax/12000.le.30) then + write(fname,1102) ifile +1102 format('000000_',i6.6,'.wav') + else + write(fname,1104) ifile +1104 format('000000_',i4.4,'.wav') + endif + open(10,file=trim(fname),status='unknown',access='stream') + write(10) h,iwave !Save to *.wav file + close(10) + write(*,1110) ifile,xdt,f00,snrdb,fname +1110 format(i4,f7.2,f8.2,f7.1,2x,a17) + enddo + +999 end program fst240sim diff --git a/lib/fst280/fst280.txt b/lib/fst240/fst280.txt similarity index 100% rename from lib/fst280/fst280.txt rename to lib/fst240/fst280.txt diff --git a/lib/fst280/fst280_params.f90 b/lib/fst240/fst280_params.f90 similarity index 100% rename from lib/fst280/fst280_params.f90 rename to lib/fst240/fst280_params.f90 diff --git a/lib/fst280/fst280d.f90 b/lib/fst240/fst280d.f90 similarity index 100% rename from lib/fst280/fst280d.f90 rename to lib/fst240/fst280d.f90 diff --git a/lib/fst280/fst280sim.f90 b/lib/fst240/fst280sim.f90 similarity index 100% rename from lib/fst280/fst280sim.f90 rename to lib/fst240/fst280sim.f90 diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst240/gen_fst240wave.f90 new file mode 100644 index 000000000..3005968b2 --- /dev/null +++ b/lib/fst240/gen_fst240wave.f90 @@ -0,0 +1,98 @@ +subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & + icmplx,cwave,wave) + + parameter(NTAB=65536) + real wave(nwave) + complex cwave(nwave),ctab(0:NTAB-1) + real, allocatable, save :: pulse(:) + real, allocatable :: dphi(:) + integer hmod + integer itone(nsym) +! integer*8 count0,count1,clkfreq + logical first + data first/.true./ + data nsps0/-99/ + save first,twopi,dt,tsym,nsps0,ctab + +! call system_clock(count0,clkfreq) + if(first) then + twopi=8.0*atan(1.0) + do i=0,NTAB-1 + phi=i*twopi/NTAB + ctab(i)=cmplx(cos(phi),sin(phi)) + enddo + endif + + if(first.or.nsps.ne.nsps0) then + if(allocated(pulse)) deallocate(pulse) + allocate(pulse(1:3*nsps)) + dt=1.0/fsample + tsym=nsps/fsample +! Compute the smoothed frequency-deviation pulse + do i=1,3*nsps + tt=(i-1.5*nsps)/real(nsps) + pulse(i)=gfsk_pulse(2.0,tt) + enddo + first=.false. + nsps0=nsps + endif + +! Compute the smoothed frequency waveform. +! Length = (nsym+2)*nsps samples, zero-padded + allocate( dphi(0:(nsym+2)*nsps-1) ) + dphi_peak=twopi*hmod/real(nsps) + dphi=0.0 + do j=1,nsym + ib=(j-1)*nsps + ie=ib+3*nsps-1 + dphi(ib:ie) = dphi(ib:ie) + dphi_peak*pulse(1:3*nsps)*itone(j) + enddo + +! Calculate and insert the audio waveform + phi=0.0 + dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 + if(icmplx.eq.0) wave=0. + if(icmplx.eq.1) cwave=0. + k=0 + do j=0,(nsym+2)*nsps-1 + k=k+1 + i=phi*float(NTAB)/twopi + i=iand(i,NTAB-1) + if(icmplx.eq.0) then + wave(k)=real(ctab(i)) + else + cwave(k)=ctab(i) + endif + phi=phi+dphi(j) + if(phi.gt.twopi) phi=phi-twopi + enddo + +! Compute the ramp-up and ramp-down symbols + kshift=nsps-nint(fsample) + if(icmplx.eq.0) then + wave(1:nsps)=0.0 + wave(nsps+1:nsps+nsps/4)=wave(nsps+1:nsps+nsps/4) * & + (1.0-cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + k1=nsym*nsps+3*nsps/4 + wave((nsym+1)*nsps+1:)=0.0 + wave(k1:k1+nsps/4-1)=wave(k1:k1+nsps/4-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + wave=cshift(wave,kshift) + else + cwave(1:nsps)=0.0 + cwave(nsps+1:nsps+nsps/4)=cwave(nsps+1:nsps+nsps/4) * & + (1.0-cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + k1=nsym*nsps+3*nsps/4 + cwave((nsym+1)*nsps+1:)=0.0 + cwave(k1:k1+nsps/4-1)=cwave(k1:k1+nsps/4-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + cwave=cshift(cwave,kshift) + endif + +! call system_clock(count1,clkfreq) +! tt=float(count1-count0)/float(clkfreq) +! write(*,3001) tt +!3001 format('Tgen:',f8.3) + + return +end subroutine gen_fst240wave diff --git a/lib/fst280/gen_fst280wave.f90 b/lib/fst240/gen_fst280wave.f90 similarity index 100% rename from lib/fst280/gen_fst280wave.f90 rename to lib/fst240/gen_fst280wave.f90 diff --git a/lib/fst240/genfst240.f90 b/lib/fst240/genfst240.f90 new file mode 100644 index 000000000..4cf688308 --- /dev/null +++ b/lib/fst240/genfst240.f90 @@ -0,0 +1,101 @@ +subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) + +! Input: +! - msg0 requested message to be transmitted +! - ichk if ichk=1, return only msgsent +! - msgsent message as it will be decoded +! - i4tone array of audio tone values, {0,1,2,3} +! - iwspr 0: (240,101)/crc24, 1: (240,74)/crc24 +! +! Frame structure: +! s8 d30 s8 d30 s8 d30 s8 d30 s8 + + use packjt77 + include 'fst240_params.f90' + character*37 msg0 + character*37 message !Message to be generated + character*37 msgsent !Message as it will be received + character*77 c77 + character*24 c24 + integer*4 i4tone(NN),itmp(ND) + integer*1 codeword(2*ND) + integer*1 msgbits(101),rvec(77) + integer isyncword(8) + integer ncrc24 + logical unpk77_success + data isyncword/0,1,3,2,1,0,2,3/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ + message=msg0 + + do i=1, 37 + if(ichar(message(i:i)).eq.0) then + message(i:37)=' ' + exit + endif + enddo + do i=1,37 !Strip leading blanks + if(message(1:1).ne.' ') exit + message=message(i+1:) + enddo + + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) + call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent + msgbits=0 + iwspr=0 + if(i3.eq.0.and.n3.eq.6) then + iwspr=1 + read(c77,'(50i1)') msgbits(1:50) + call get_crc24(msgbits,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(51:74) + else + read(c77,'(77i1)') msgbits(1:77) + call get_crc24(msgbits,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(78:101) + endif + + if(ichk.eq.1) go to 999 + if(unpk77_success) go to 2 +1 msgbits=0 + itone=0 + msgsent='*** bad message *** ' + go to 999 + + entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) + +2 continue + + call encode240_101(msgbits,codeword) + +! Grayscale mapping: +! bits tone +! 00 0 +! 01 1 +! 11 2 +! 10 3 + + do i=1,ND + is=codeword(2*i)+2*codeword(2*i-1) + if(is.le.1) itmp(i)=is + if(is.eq.2) itmp(i)=3 + if(is.eq.3) itmp(i)=2 + enddo + + i4tone( 1: 8)=isyncword + i4tone( 9: 38)=itmp( 1: 30) + i4tone( 39: 46)=isyncword + i4tone( 47: 76)=itmp( 31: 60) + i4tone( 77: 84)=isyncword + i4tone( 85:114)=itmp( 61: 90) + i4tone(115:122)=isyncword + i4tone(123:152)=itmp( 91:120) + i4tone(153:160)=isyncword + +999 return + +end subroutine genfst240 diff --git a/lib/fst280/genfst280.f90 b/lib/fst240/genfst280.f90 similarity index 100% rename from lib/fst280/genfst280.f90 rename to lib/fst240/genfst280.f90 diff --git a/lib/fst280/get_crc24.f90 b/lib/fst240/get_crc24.f90 similarity index 100% rename from lib/fst280/get_crc24.f90 rename to lib/fst240/get_crc24.f90 diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst240/get_fst240_bitmetrics.f90 new file mode 100644 index 000000000..ddefbad68 --- /dev/null +++ b/lib/fst240/get_fst240_bitmetrics.f90 @@ -0,0 +1,123 @@ +subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) + + include 'fst240_params.f90' + complex cd(0:NN*nss-1) + complex cs(0:3,NN) + complex csymb(nss) + complex, allocatable, save :: c1(:,:) ! ideal waveforms, 20 samples per symbol, 4 tones + complex cp(0:3) ! accumulated phase shift over symbol types 0:3 + complex csum,cterm + integer icos8(0:7) + integer graymap(0:3) + integer ip(1) + integer hmod + logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits + logical first + logical badsync + real bitmetrics(2*NN,4) + real s2(0:65535) + real s4(0:3,NN) + data icos8/0,1,3,2,1,0,2,3/ + data graymap/0,1,3,2/ + data first/.true./,nss0/-1/ + save first,one,cp,nss0 + + if(nss.ne.nss0 .and. allocated(c1)) deallocate(c1) + if(first .or. nss.ne.nss0) then + allocate(c1(nss,0:3)) + one=.false. + do i=0,65535 + do j=0,15 + if(iand(i,2**j).ne.0) one(i,j)=.true. + enddo + enddo + twopi=8.0*atan(1.0) + dphi=twopi*hmod/nss + do itone=0,3 + dp=(itone-1.5)*dphi + phi=0.0 + do j=1,nss + c1(j,itone)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dp,twopi) + enddo + cp(itone)=cmplx(cos(phi),sin(phi)) + enddo + first=.false. + endif + + do k=1,NN + i1=(k-1)*NSS + csymb=cd(i1:i1+NSS-1) + do itone=0,3 + cs(itone,k)=sum(csymb*conjg(c1(:,itone))) + enddo + s4(0:3,k)=abs(cs(0:3,k)) + enddo + +! Sync quality check + is1=0 + is2=0 + is3=0 + badsync=.false. + ibmax=0 + + do k=1,8 + ip=maxloc(s4(:,k)) + if(icos8(k-1).eq.(ip(1)-1)) is1=is1+1 + ip=maxloc(s4(:,k+38)) + if(icos8(k-1).eq.(ip(1)-1)) is2=is2+1 + ip=maxloc(s4(:,k+76)) + if(icos8(k-1).eq.(ip(1)-1)) is3=is3+1 + ip=maxloc(s4(:,k+114)) + if(icos8(k-1).eq.(ip(1)-1)) is4=is4+1 + ip=maxloc(s4(:,k+152)) + if(icos8(k-1).eq.(ip(1)-1)) is5=is5+1 + enddo + nsync=is1+is2+is3+is4+is5 !Number of correct hard sync symbols, 0-40 + + badsync=.false. + if(nsync .lt. 8) then + badsync=.true. + return + endif + + bitmetrics=0.0 + do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols + if(nseq.eq.1) nsym=1 + if(nseq.eq.2) nsym=2 + if(nseq.eq.3) nsym=4 + if(nseq.eq.4) nsym=8 + nt=4**nsym + do ks=1,NN-nsym+1,nsym + s2=0 + do i=0,nt-1 + csum=0 + cterm=1 + do j=0,nsym-1 + ntone=mod(i/4**(nsym-1-j),4) + csum=csum+cs(graymap(ntone),ks+j)*cterm + cterm=cterm*conjg(cp(graymap(ntone))) + enddo + s2(i)=abs(csum) + enddo + ipt=1+(ks-1)*2 + if(nsym.eq.1) ibmax=1 + if(nsym.eq.2) ibmax=3 + if(nsym.eq.4) ibmax=7 + if(nsym.eq.8) ibmax=15 + do ib=0,ibmax + bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & + maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) + if(ipt+ib.gt.2*NN) cycle + bitmetrics(ipt+ib,nseq)=bm + enddo + enddo + enddo + + call normalizebmet(bitmetrics(:,1),2*NN) + call normalizebmet(bitmetrics(:,2),2*NN) + call normalizebmet(bitmetrics(:,3),2*NN) + call normalizebmet(bitmetrics(:,4),2*NN) + return + +end subroutine get_fst240_bitmetrics diff --git a/lib/fst280/get_fst280_bitmetrics.f90 b/lib/fst240/get_fst280_bitmetrics.f90 similarity index 100% rename from lib/fst280/get_fst280_bitmetrics.f90 rename to lib/fst240/get_fst280_bitmetrics.f90 diff --git a/lib/fst240/ldpc_240_101_generator.f90 b/lib/fst240/ldpc_240_101_generator.f90 new file mode 100644 index 000000000..782e0a211 --- /dev/null +++ b/lib/fst240/ldpc_240_101_generator.f90 @@ -0,0 +1,142 @@ +character*26 g(139) + +data g/ & + "e28df133efbc554bcd30eb1828", & + "b1adf97787f81b4ac02e0caff8", & + "e70c43adce5036f847af367560", & + "c26663f7f7acafdf5abacb6f30", & + "eba93204ddfa3bcf994aea8998", & + "126b51e33c6a740afa0d5ce990", & + "b41a1569e6fede1f2f5395cb68", & + "1d3af0bb43fddbc670a291cc70", & + "e0aebd9921e2c9e1d453ffccb0", & + "897d1370f0df94b8b27a5e4fb8", & + "5e97539338003b13fa8198ad38", & + "7276b87da4a4d777e2752fdd48", & + "989888bd3a85835e2bc6a560f8", & + "7ec4f4a56199ab0a8d6e102478", & + "207007665090258782d1b38a98", & + "1ea1f61cd7f0b7eed7dd346ab8", & + "08f150b27c7f18a027783de0e8", & + "d42324a4e21b62d548d7865858", & + "2e029656269d4fe46e167d21d0", & + "7d84acb7737b0ca6b6f2ef5eb0", & + "6674ca04528ad4782bf5e15248", & + "118ce9825f563ae4963af7a0b0", & + "fb06248cc985e314b1b36ccd38", & + "1c478b7a5aec7e1cfc9c24eb70", & + "185a0f06a84f7f4f484c455020", & + "98b840a3a70688cd58588e3e30", & + "cfb7719de83a3baf582e5b2aa0", & + "9d8cc6b5a01fdbfa307a769048", & + "ed776a728ca162d6fcc8996760", & + "8d2b068128dfb2f8d22c79db50", & + "bd2ba50007789ffb7324aa9190", & + "fd95008fe88812025e78065610", & + "3027849be8e99f9ef68eac1020", & + "88574e1ea39d87414b15e803a8", & + "89365b330e76e6dde740dced08", & + "c83f37b913ed0f6b802aaf21d8", & + "bdca7c1959caa7488b7eb13030", & + "794e0b4888e1ef42992287dd98", & + "526ac87fbaa790c6cd58864e08", & + "940518ba1a51c1da55bc8b2d70", & + "59c5e51ebfbd02ab30ff822378", & + "c81fff87866e04f8f3948c7f10", & + "7913513f3e2a3c0f76b69f6d68", & + "e43cc04da189c44803c4f740a0", & + "fdca7c1959ca85488b7eb13030", & + "95b07fce9b7b1bf4f057ca61b8", & + "d7db48a86691a0c0c9305aac90", & + "0d50bf79a59464597c43ba8058", & + "4a9c34b23fd5eaff8c9dc215e0", & + "3d5305a6f0427938eeb9d1c118", & + "55d8b6b58039f7a3a2d592a900", & + "784f349ecb74c4abbdbb073b90", & + "5973bbb2205f9d6a5c9a55c238", & + "5d2ee61006fec94f69f6b0f460", & + "9e1f52ef1e6589990dd0ce0cc8", & + "85b7b48f4b45775c9f8a36cc90", & + "ae1d6a0171168f6d70804b79f8", & + "a467aa9aa6cdc7094677c730d8", & + "dcf2f56c9ae20fb57e89b916d0", & + "3ae98d26ae96ea714c1a5146d0", & + "103c89581446805b8c71b2e638", & + "6783f3dfec835dd4e92131cc20", & + "52f88428c50f12c55876f7d8a8", & + "51fcb0e56a22fa3b7140aeaa80", & + "07c54871155603e65325f66cd8", & + "a8dd4fac47a113ee5706eef180", & + "f6cdc6f4cc1fa7e4db15bf86f8", & + "2e1c6a0171168f6d70c04a79f8", & + "2a90ab82bef6424db981752dc8", & + "845a1db59c193249d937e889d0", & + "a929d379f1769cb4baa4e41e90", & + "0c2a5829548d82223d6f566d48", & + "420087bc5c4e2f5bc139ad0220", & + "6df8d880ae7209fe52c69ede00", & + "dfbdcef29a985fd40d052d1a88", & + "8567fc332342b1ed8408f5fa00", & + "c908feb4e1866a24ca0c702a08", & + "645f5ee59f9f64fd43a5f2ec30", & + "bee56991e877baf3e9cf11b770", & + "649ea2e4194ca51be28abf3430", & + "90e7394c551bd58d00686d5420", & + "4e3cf731f8f89e8414214afaf0", & + "dcbf16aa8180a7712571e94f98", & + "9b456c015999c52b7fbd1ab390", & + "397ab76924659c4b8b3be4ac58", & + "4f5038c4f9da4b02bdfa178278", & + "4892fada978c98dd4fd363c450", & + "6c8af64b426bc474431c110c98", & + "84a553be5ef0e57390a5af05b0", & + "bed4a9347c9a2064f6d63ac0f8", & + "d973bbb2605f9d6a5c9a57c238", & + "1e3bee9a99fe10d3864ee669d8", & + "a590771ff185d807cb32f46000", & + "9a498fc4b549d81c625f80fc90", & + "28b3e72878aadee7e0e2617950", & + "96ce025d621a91396aa8f3ec20", & + "4f5a77becf838a590d6d406ea8", & + "52d3856dfb9fe78012f10e25c0", & + "b45323c2b28b4752ca0675d2e0", & + "3bae5a8452a785beb35851ad18", & + "65098832d20d915e75bea336e8", & + "5eb6f3c331098e8c0fbfa3aee0", & + "ef19d974a25540c8998fbf1df0", & + "403ea58feff08cf92d5cacc780", & + "6ba93204ddfa7bcb994aea8998", & + "653909166aa7bead4bd9c90020", & + "089cb20e639bc5a44da66f17c0", & + "10f803949961359e994f5ade88", & + "15b7ec1e6106cd55ef7d996590", & + "c99e99de9d85d2b999a17a95d8", & + "ca3e161b97148bac6dd28a6178", & + "e1ab199c992cb4c22aee115358", & + "ea8a4d0e96d3d9f827899b6d88", & + "8af4992d60223f021569a8ab60", & + "5087771abceb87a6d872291fe8", & + "d045e0812e217bb7bbdac92f30", & + "ccccd78ae5fa6e191f21c06908", & + "54545f37df6fed4734ef6509b0", & + "b0780327d899cbc03d95a81a48", & + "a4229c31f2b85e44a322273d50", & + "d182ab001c2085ea7be26a20d0", & + "1a82c30b4fba7dfaafb8d287a8", & + "d974fba598e7fb0630c1587db0", & + "b5c078a8cbab3e73728659ea20", & + "626bbf9eed1a8715c3a7d38f60", & + "c1efe9aa67130865fda93d8be8", & + "d39796dbce155df6306e7b77c0", & + "c7e7c1f032d7209b4549e84aa8", & + "d5799b30a1605baf6b9cd04960", & + "0baf2d21051a926dfd87046d70", & + "da8bf7d1e305c499b573c02cc8", & + "0ccaa7fffb9ae3e42dd0688328", & + "b951b62e18f5290ac13c195130", & + "79b006f001961fb233be80d0e8", & + "56637b6dedfd6e050f06404a48", & + "e0c4bf71a15597523bbd57bde0", & + "1312231ffa04426a34a8fab038", & + "db5f6f0455d24b8358d1cbc3d8", & + "d559e31b34d21f48e1f501af30"/ diff --git a/lib/fst240/ldpc_240_101_parity.f90 b/lib/fst240/ldpc_240_101_parity.f90 new file mode 100644 index 000000000..d3c1280c6 --- /dev/null +++ b/lib/fst240/ldpc_240_101_parity.f90 @@ -0,0 +1,393 @@ +data Mn/ & + 57, 100, 134, & + 56, 99, 136, & + 1, 12, 15, & + 2, 23, 72, & + 3, 133, 137, & + 4, 93, 125, & + 5, 68, 139, & + 6, 38, 55, & + 7, 40, 78, & + 8, 30, 84, & + 9, 17, 122, & + 10, 34, 95, & + 11, 36, 138, & + 13, 90, 132, & + 14, 50, 117, & + 16, 57, 83, & + 18, 22, 121, & + 19, 60, 89, & + 20, 98, 107, & + 21, 37, 61, & + 24, 26, 75, & + 25, 88, 115, & + 27, 49, 127, & + 28, 74, 119, & + 29, 111, 114, & + 31, 91, 129, & + 32, 96, 104, & + 30, 33, 130, & + 35, 65, 135, & + 41, 42, 87, & + 44, 108, 131, & + 45, 94, 101, & + 45, 46, 97, & + 47, 102, 134, & + 48, 64, 104, & + 19, 51, 116, & + 20, 52, 67, & + 53, 104, 113, & + 12, 54, 103, & + 58, 66, 88, & + 62, 80, 124, & + 63, 70, 71, & + 73, 114, 123, & + 76, 85, 128, & + 77, 106, 109, & + 46, 79, 126, & + 61, 81, 110, & + 82, 92, 120, & + 86, 105, 112, & + 66, 100, 118, & + 23, 51, 136, & + 1, 40, 53, & + 2, 73, 81, & + 3, 63, 130, & + 4, 68, 136, & + 5, 60, 78, & + 6, 72, 131, & + 7, 115, 124, & + 8, 89, 120, & + 9, 15, 44, & + 10, 22, 93, & + 11, 49, 100, & + 13, 55, 80, & + 14, 76, 95, & + 16, 54, 111, & + 17, 41, 110, & + 18, 69, 139, & + 21, 24, 116, & + 25, 39, 71, & + 26, 69, 90, & + 27, 101, 133, & + 28, 64, 126, & + 29, 94, 103, & + 31, 56, 57, & + 32, 91, 102, & + 33, 35, 129, & + 34, 47, 128, & + 36, 86, 117, & + 37, 74, 75, & + 38, 79, 106, & + 42, 82, 123, & + 43, 77, 99, & + 48, 70, 92, & + 50, 109, 118, & + 52, 112, 119, & + 58, 62, 108, & + 59, 84, 134, & + 57, 65, 122, & + 67, 97, 113, & + 83, 127, 135, & + 85, 121, 125, & + 87, 132, 137, & + 96, 98, 105, & + 73, 107, 138, & + 1, 83, 89, & + 2, 41, 70, & + 3, 35, 131, & + 4, 111, 128, & + 5, 29, 99, & + 6, 25, 31, & + 7, 19, 96, & + 1, 39, 110, & + 2, 7, 117, & + 3, 49, 109, & + 4, 81, 96, & + 5, 100, 108, & + 6, 51, 124, & + 2, 20, 132, & + 8, 80, 137, & + 9, 56, 67, & + 10, 63, 102, & + 11, 16, 101, & + 12, 115, 122, & + 13, 32, 128, & + 14, 15, 130, & + 14, 70, 99, & + 11, 51, 69, & + 17, 89, 105, & + 18, 83, 99, & + 19, 44, 79, & + 20, 106, 133, & + 10, 21, 123, & + 22, 23, 61, & + 16, 22, 60, & + 24, 38, 114, & + 25, 37, 42, & + 26, 43, 52, & + 27, 68, 71, & + 28, 65, 139, & + 29, 62, 69, & + 30, 92, 126, & + 31, 78, 123, & + 13, 44, 78, & + 33, 40, 120, & + 7, 34, 119, & + 4, 35, 77, & + 12, 36, 52, & + 25, 98, 136, & + 5, 24, 133, & + 1, 80, 91, & + 33, 96, 97, & + 34, 41, 91, & + 32, 37, 117, & + 26, 72, 125, & + 19, 65, 75, & + 45, 131, 136, & + 46, 55, 70, & + 47, 48, 50, & + 6, 48, 94, & + 3, 74, 79, & + 39, 50, 126, & + 23, 118, 127, & + 21, 36, 113, & + 53, 77, 134, & + 30, 54, 55, & + 17, 46, 135, & + 9, 92, 102, & + 57, 85, 87, & + 58, 125, 138, & + 59, 76, 93, & + 60, 66, 107, & + 47, 132, 138, & + 29, 85, 131, & + 43, 73, 108, & + 64, 75, 129, & + 28, 38, 53, & + 61, 106, 122, & + 56, 71, 114, & + 27, 57, 120, & + 62, 67, 130, & + 54, 104, 118, & + 8, 68, 115, & + 72, 86, 111, & + 73, 74, 94, & + 49, 105, 113, & + 42, 86, 121, & + 40, 59, 109, & + 35, 88, 95, & + 31, 107, 112, & + 58, 64, 87, & + 68, 79, 104, & + 1, 5, 121, & + 15, 82, 93, & + 18, 88, 116, & + 82, 84, 119, & + 7, 71, 103, & + 4, 80, 94, & + 63, 81, 84, & + 66, 76, 137, & + 83, 124, 129, & + 90, 112, 116, & + 89, 111, 134, & + 6, 21, 120, & + 3, 16, 25, & + 12, 28, 131, & + 45, 95, 110, & + 17, 93, 124, & + 97, 121, 127, & + 98, 103, 135, & + 8, 99, 138, & + 41, 101, 139, & + 13, 24, 105, & + 14, 53, 107, & + 10, 64, 98, & + 11, 35, 78, & + 90, 100, 103, & + 9, 72, 101, & + 18, 74, 92, & + 15, 73, 87, & + 2, 88, 113, & + 20, 55, 85, & + 19, 67, 110, & + 26, 27, 95, & + 22, 50, 114, & + 29, 49, 81, & + 32, 52, 83, & + 30, 37, 77, & + 39, 128, 135, & + 23, 128, 130, & + 36, 76, 126, & + 33, 132, 139, & + 34, 89, 118, & + 38, 58, 127, & + 31, 54, 125, & + 40, 70, 75, & + 41, 109, 116, & + 43, 60, 63, & + 44, 84, 86, & + 42, 47, 62, & + 45, 82, 90, & + 43, 46, 91, & + 48, 112, 122, & + 51, 102, 133, & + 59, 61, 108, & + 65, 117, 137, & + 56, 66, 96, & + 59, 69, 104, & + 39, 69, 119, & + 97, 115, 123, & + 106, 111, 129/ + +data Nm/ & + 3, 52, 95, 102, 140, 182, & + 4, 53, 96, 103, 108, 210, & + 5, 54, 97, 104, 150, 194, & + 6, 55, 98, 105, 136, 187, & + 7, 56, 99, 106, 139, 182, & + 8, 57, 100, 107, 149, 193, & + 9, 58, 101, 103, 135, 186, & + 10, 59, 109, 172, 200, 0, & + 11, 60, 110, 157, 207, 0, & + 12, 61, 111, 122, 204, 0, & + 13, 62, 112, 117, 205, 0, & + 3, 39, 113, 137, 195, 0, & + 14, 63, 114, 133, 202, 0, & + 15, 64, 115, 116, 203, 0, & + 3, 60, 115, 183, 209, 0, & + 16, 65, 112, 124, 194, 0, & + 11, 66, 118, 156, 197, 0, & + 17, 67, 119, 184, 208, 0, & + 18, 36, 101, 120, 145, 212, & + 19, 37, 108, 121, 211, 0, & + 20, 68, 122, 153, 193, 0, & + 17, 61, 123, 124, 214, 0, & + 4, 51, 123, 152, 219, 0, & + 21, 68, 125, 139, 202, 0, & + 22, 69, 100, 126, 138, 194, & + 21, 70, 127, 144, 213, 0, & + 23, 71, 128, 169, 213, 0, & + 24, 72, 129, 166, 195, 0, & + 25, 73, 99, 130, 163, 215, & + 10, 28, 131, 155, 217, 0, & + 26, 74, 100, 132, 179, 224, & + 27, 75, 114, 143, 216, 0, & + 28, 76, 134, 141, 221, 0, & + 12, 77, 135, 142, 222, 0, & + 29, 76, 97, 136, 178, 205, & + 13, 78, 137, 153, 220, 0, & + 20, 79, 126, 143, 217, 0, & + 8, 80, 125, 166, 223, 0, & + 69, 102, 151, 218, 238, 0, & + 9, 52, 134, 177, 225, 0, & + 30, 66, 96, 142, 201, 226, & + 30, 81, 126, 176, 229, 0, & + 82, 127, 164, 227, 231, 0, & + 31, 60, 120, 133, 228, 0, & + 32, 33, 146, 196, 230, 0, & + 33, 46, 147, 156, 231, 0, & + 34, 77, 148, 162, 229, 0, & + 35, 83, 148, 149, 232, 0, & + 23, 62, 104, 175, 215, 0, & + 15, 84, 148, 151, 214, 0, & + 36, 51, 107, 117, 233, 0, & + 37, 85, 127, 137, 216, 0, & + 38, 52, 154, 166, 203, 0, & + 39, 65, 155, 171, 224, 0, & + 8, 63, 147, 155, 211, 0, & + 2, 74, 110, 168, 236, 0, & + 1, 16, 74, 88, 158, 169, & + 40, 86, 159, 180, 223, 0, & + 87, 160, 177, 234, 237, 0, & + 18, 56, 124, 161, 227, 0, & + 20, 47, 123, 167, 234, 0, & + 41, 86, 130, 170, 229, 0, & + 42, 54, 111, 188, 227, 0, & + 35, 72, 165, 180, 204, 0, & + 29, 88, 129, 145, 235, 0, & + 40, 50, 161, 189, 236, 0, & + 37, 89, 110, 170, 212, 0, & + 7, 55, 128, 172, 181, 0, & + 67, 70, 117, 130, 237, 238, & + 42, 83, 96, 116, 147, 225, & + 42, 69, 128, 168, 186, 0, & + 4, 57, 144, 173, 207, 0, & + 43, 53, 94, 164, 174, 209, & + 24, 79, 150, 174, 208, 0, & + 21, 79, 145, 165, 225, 0, & + 44, 64, 160, 189, 220, 0, & + 45, 82, 136, 154, 217, 0, & + 9, 56, 132, 133, 205, 0, & + 46, 80, 120, 150, 181, 0, & + 41, 63, 109, 140, 187, 0, & + 47, 53, 105, 188, 215, 0, & + 48, 81, 183, 185, 230, 0, & + 16, 90, 95, 119, 190, 216, & + 10, 87, 185, 188, 228, 0, & + 44, 91, 158, 163, 211, 0, & + 49, 78, 173, 176, 228, 0, & + 30, 92, 158, 180, 209, 0, & + 22, 40, 178, 184, 210, 0, & + 18, 59, 95, 118, 192, 222, & + 14, 70, 191, 206, 230, 0, & + 26, 75, 140, 142, 231, 0, & + 48, 83, 131, 157, 208, 0, & + 6, 61, 160, 183, 197, 0, & + 32, 73, 149, 174, 187, 0, & + 12, 64, 178, 196, 213, 0, & + 27, 93, 101, 105, 141, 236, & + 33, 89, 141, 198, 239, 0, & + 19, 93, 138, 199, 204, 0, & + 2, 82, 99, 116, 119, 200, & + 1, 50, 62, 106, 206, 0, & + 32, 71, 112, 201, 207, 0, & + 34, 75, 111, 157, 233, 0, & + 39, 73, 186, 199, 206, 0, & + 27, 35, 38, 171, 181, 237, & + 49, 93, 118, 175, 202, 0, & + 45, 80, 121, 167, 240, 0, & + 19, 94, 161, 179, 203, 0, & + 31, 86, 106, 164, 234, 0, & + 45, 84, 104, 177, 226, 0, & + 47, 66, 102, 196, 212, 0, & + 25, 65, 98, 173, 192, 240, & + 49, 85, 179, 191, 232, 0, & + 38, 89, 153, 175, 210, 0, & + 25, 43, 125, 168, 214, 0, & + 22, 58, 113, 172, 239, 0, & + 36, 68, 184, 191, 226, 0, & + 15, 78, 103, 143, 235, 0, & + 50, 84, 152, 171, 222, 0, & + 24, 85, 135, 185, 238, 0, & + 48, 59, 134, 169, 193, 0, & + 17, 91, 176, 182, 198, 0, & + 11, 88, 113, 167, 232, 0, & + 43, 81, 122, 132, 239, 0, & + 41, 58, 107, 190, 197, 0, & + 6, 91, 144, 159, 224, 0, & + 46, 72, 131, 151, 220, 0, & + 23, 90, 152, 198, 223, 0, & + 44, 77, 98, 114, 218, 219, & + 26, 76, 165, 190, 240, 0, & + 28, 54, 115, 170, 219, 0, & + 31, 57, 97, 146, 163, 195, & + 14, 92, 108, 162, 221, 0, & + 5, 71, 121, 139, 233, 0, & + 1, 34, 87, 154, 192, 0, & + 29, 90, 156, 199, 218, 0, & + 2, 51, 55, 138, 146, 0, & + 5, 92, 109, 189, 235, 0, & + 13, 94, 159, 162, 200, 0, & + 7, 67, 129, 201, 221, 0/ + +data nrw/ & +6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,5, & +5,5,5,5,6,5,5,5,6,5,6,5,5,5,6,5,5,5,5,5, & +6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5, & +5,5,5,5,5,5,5,5,6,6,5,5,6,5,5,5,5,5,5,5, & +5,5,6,5,5,5,5,5,6,5,5,5,5,5,5,6,5,5,6,5, & +5,5,5,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5, & +5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5/ + +ncw=3 diff --git a/lib/fst280/ldpc_280_101_generator.f90 b/lib/fst240/ldpc_280_101_generator.f90 similarity index 100% rename from lib/fst280/ldpc_280_101_generator.f90 rename to lib/fst240/ldpc_280_101_generator.f90 diff --git a/lib/fst280/ldpc_280_101_parity.f90 b/lib/fst240/ldpc_280_101_parity.f90 similarity index 100% rename from lib/fst280/ldpc_280_101_parity.f90 rename to lib/fst240/ldpc_280_101_parity.f90 diff --git a/lib/fst280/ldpc_280_74_generator.f90 b/lib/fst240/ldpc_280_74_generator.f90 similarity index 100% rename from lib/fst280/ldpc_280_74_generator.f90 rename to lib/fst240/ldpc_280_74_generator.f90 diff --git a/lib/fst280/ldpc_280_74_parity.f90 b/lib/fst240/ldpc_280_74_parity.f90 similarity index 100% rename from lib/fst280/ldpc_280_74_parity.f90 rename to lib/fst240/ldpc_280_74_parity.f90 diff --git a/lib/fst240/ldpcsim240_101.f90 b/lib/fst240/ldpcsim240_101.f90 new file mode 100644 index 000000000..55121b5c3 --- /dev/null +++ b/lib/fst240/ldpcsim240_101.f90 @@ -0,0 +1,143 @@ +program ldpcsim240_101 + +! End-to-end test of the (240,101)/crc24 encoder and decoders. + + use packjt77 + + parameter(N=240, K=101, M=N-K) + character*8 arg + character*37 msg0,msg + character*77 c77 + character*24 c24 + integer*1 msgbits(101) + integer*1 apmask(240) + integer*1 cw(240) + integer*1 codeword(N),message101(101) + integer ncrc24 + real rxdata(N),llr(N) + logical first,unpk77_success + data first/.true./ + + nargs=iargc() + if(nargs.ne.5 .and. nargs.ne.6) then + print*,'Usage: ldpcsim niter ndeep #trials s K [msg]' + print*,'e.g. ldpcsim240_101 20 5 1000 0.85 91 "K9AN K1JT FN20"' + print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' + print*,'niter: is the number of BP iterations.' + print*,'ndeep: -1 is BP only, ndeep>=0 is OSD order' + print*,'K :is the number of message+CRC bits and must be in the range [77,101]' + print*,'WSPR-format message is optional' + return + endif + call getarg(1,arg) + read(arg,*) max_iterations + call getarg(2,arg) + read(arg,*) ndeep + call getarg(3,arg) + read(arg,*) ntrials + call getarg(4,arg) + read(arg,*) s + call getarg(5,arg) + read(arg,*) Keff + msg0='K9AN K1JT FN20 ' + if(nargs.eq.6) call getarg(6,msg0) + call pack77(msg0,i3,n3,c77) + + rate=real(Keff)/real(N) + + write(*,*) "code rate: ",rate + write(*,*) "niter : ",max_iterations + write(*,*) "ndeep : ",ndeep + write(*,*) "s : ",s + write(*,*) "K : ",Keff + + msgbits=0 + read(c77,'(77i1)') msgbits(1:77) + write(*,*) 'message' + write(*,'(77i1)') msgbits(1:77) + + call get_crc24(msgbits,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(78:101) +write(*,'(24i1)') msgbits(78:101) + write(*,*) 'message with crc24' + write(*,'(101i1)') msgbits(1:101) + call encode240_101(msgbits,codeword) + call init_random_seed() + call sgran() + + write(*,*) 'codeword' + write(*,'(77i1,1x,24i1,1x,73i1)') codeword + + write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" + do idb = 8,-3,-1 + db=idb/2.0-1.0 + sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No +! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No + ngood=0 + nue=0 + nberr=0 + do itrial=1, ntrials +! Create a realization of a noisy received word + do i=1,N + rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() + enddo + nerr=0 + do i=1,N + if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 + enddo + nberr=nberr+nerr + + rxav=sum(rxdata)/N + rx2av=sum(rxdata*rxdata)/N + rxsig=sqrt(rx2av-rxav*rxav) + rxdata=rxdata/rxsig + if( s .lt. 0 ) then + ss=sigma + else + ss=s + endif + + llr=2.0*rxdata/(ss*ss) + apmask=0 +! max_iterations is max number of belief propagation iterations + call bpdecode240_101(llr,apmask,max_iterations,message101,cw,nharderror,niterations,nchecks) + dmin=0.0 + if( (nharderror .lt. 0) .and. (ndeep .ge. 0) ) then +! call osd240_101(llr, Keff, apmask, ndeep, message101, cw, nharderror, dmin) + maxsuper=2 + call decode240_101(llr, Keff, ndeep, apmask, maxsuper, message101, cw, nharderror, iterations, ncheck, dmin, isuper) + endif + + if(nharderror.ge.0) then + n2err=0 + do i=1,N + if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 + enddo + if(n2err.eq.0) then + ngood=ngood+1 + else + nue=nue+1 + endif + endif + enddo +! snr2500=db+10*log10(200.0/116.0/2500.0) + esn0=db+10*log10(rate) + pberr=real(nberr)/(real(ntrials*N)) + write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr + + if(first) then + write(c77,'(77i1)') message101(1:77) +write(*,'(101i1)') message101 + call unpack77(c77,0,msg,unpk77_success) + if(unpk77_success) then + write(*,1100) msg(1:37) +1100 format('Decoded message: ',a37) + else + print*,'Error unpacking message' + endif + first=.false. + endif + enddo + +end program ldpcsim240_101 diff --git a/lib/fst280/ldpcsim280_101.f90 b/lib/fst240/ldpcsim280_101.f90 similarity index 100% rename from lib/fst280/ldpcsim280_101.f90 rename to lib/fst240/ldpcsim280_101.f90 diff --git a/lib/fst280/ldpcsim280_74.f90 b/lib/fst240/ldpcsim280_74.f90 similarity index 100% rename from lib/fst280/ldpcsim280_74.f90 rename to lib/fst240/ldpcsim280_74.f90 diff --git a/lib/fst240/osd240_101.f90 b/lib/fst240/osd240_101.f90 new file mode 100644 index 000000000..5e9f5d195 --- /dev/null +++ b/lib/fst240/osd240_101.f90 @@ -0,0 +1,403 @@ +subroutine osd240_101(llr,k,apmask,ndeep,message101,cw,nhardmin,dmin) +! +! An ordered-statistics decoder for the (240,101) code. +! Message payload is 77 bits. Any or all of a 24-bit CRC can be +! used for detecting incorrect codewords. The remaining CRC bits are +! cascaded with the LDPC code for the purpose of improving the +! distance spectrum of the code. +! +! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are +! to be used for bad codeword detection, then the argument k should +! be set to 77+p1. +! +! Valid values for k are in the range [77,101]. +! + character*24 c24 + integer, parameter:: N=240 + integer*1 apmask(N),apmaskr(N) + integer*1, allocatable, save :: gen(:,:) + integer*1, allocatable :: genmrb(:,:),g2(:,:) + integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) + integer*1, allocatable :: r2pat(:) + integer indices(N),nxor(N) + integer*1 cw(N),ce(N),c0(N),hdec(N) + integer*1, allocatable :: decoded(:) + integer*1 message101(101) + integer indx(N) + real llr(N),rx(N),absrx(N) + + logical first,reset + data first/.true./ + save first + + allocate( genmrb(k,N), g2(N,k) ) + allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) + allocate( r2pat(N-k), decoded(k) ) + + if( first ) then ! fill the generator matrix +! +! Create generator matrix for partial CRC cascaded with LDPC code. +! +! Let p2=101-k and p1+p2=24. +! +! The last p2 bits of the CRC24 are cascaded with the LDPC code. +! +! The first p1=k-77 CRC24 bits will be used for error detection. +! + allocate( gen(k,N) ) + gen=0 + do i=1,k + message101=0 + message101(i)=1 + if(i.le.77) then + call get_crc24(message101,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') message101(78:101) + message101(78:k)=0 + endif + call encode240_101(message101,cw) + gen(i,:)=cw + enddo + + first=.false. + endif + + rx=llr + apmaskr=apmask + +! Hard decisions on the received word. + hdec=0 + where(rx .ge. 0) hdec=1 + +! Use magnitude of received symbols as a measure of reliability. + absrx=abs(rx) + call indexx(absrx,N,indx) + +! Re-order the columns of the generator matrix in order of decreasing reliability. + do i=1,N + genmrb(1:k,i)=gen(1:k,indx(N+1-i)) + indices(i)=indx(N+1-i) + enddo + +! Do gaussian elimination to create a generator matrix with the most reliable +! received bits in positions 1:k in order of decreasing reliability (more or less). + do id=1,k ! diagonal element indices + do icol=id,k+20 ! The 20 is ad hoc - beware + iflag=0 + if( genmrb(id,icol) .eq. 1 ) then + iflag=1 + if( icol .ne. id ) then ! reorder column + temp(1:k)=genmrb(1:k,id) + genmrb(1:k,id)=genmrb(1:k,icol) + genmrb(1:k,icol)=temp(1:k) + itmp=indices(id) + indices(id)=indices(icol) + indices(icol)=itmp + endif + do ii=1,k + if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then + genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) + endif + enddo + exit + endif + enddo + enddo + + g2=transpose(genmrb) + +! The hard decisions for the k MRB bits define the order 0 message, m0. +! Encode m0 using the modified generator matrix to find the "order 0" codeword. +! Flip various combinations of bits in m0 and re-encode to generate a list of +! codewords. Return the member of the list that has the smallest Euclidean +! distance to the received word. + + hdec=hdec(indices) ! hard decisions from received symbols + m0=hdec(1:k) ! zero'th order message + absrx=absrx(indices) + rx=rx(indices) + apmaskr=apmaskr(indices) + + call mrbencode101(m0,c0,g2,N,k) + nxor=ieor(c0,hdec) + nhardmin=sum(nxor) + dmin=sum(nxor*absrx) + + cw=c0 + ntotal=0 + nrejected=0 + npre1=0 + npre2=0 + + if(ndeep.eq.0) goto 998 ! norder=0 + if(ndeep.gt.6) ndeep=6 + if( ndeep.eq. 1) then + nord=1 + npre1=0 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.2) then + nord=1 + npre1=1 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.3) then + nord=1 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=14 + elseif(ndeep.eq.4) then + nord=2 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=17 + elseif(ndeep.eq.5) then + nord=3 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=15 + elseif(ndeep.eq.6) then + nord=4 + npre1=1 + npre2=1 + nt=95 + ntheta=12 + ntau=15 + endif + + do iorder=1,nord + misub(1:k-iorder)=0 + misub(k-iorder+1:k)=1 + iflag=k-iorder+1 + do while(iflag .ge.0) + if(iorder.eq.nord .and. npre1.eq.0) then + iend=iflag + else + iend=1 + endif + d1=0. + do n1=iflag,iend,-1 + mi=misub + mi(n1)=1 + if(any(iand(apmaskr(1:k),mi).eq.1)) cycle + ntotal=ntotal+1 + me=ieor(m0,mi) + if(n1.eq.iflag) then + call mrbencode101(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + e2=e2sub + nd1kpt=sum(e2sub(1:nt))+1 + d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) + else + e2=ieor(e2sub,g2(k+1:N,n1)) + nd1kpt=sum(e2(1:nt))+2 + endif + if(nd1kpt .le. ntheta) then + call mrbencode101(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + if(n1.eq.iflag) then + dd=d1+sum(e2sub*absrx(k+1:N)) + else + dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) + endif + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + nd1kptbest=nd1kpt + endif + else + nrejected=nrejected+1 + endif + enddo +! Get the next test error pattern, iflag will go negative +! when the last pattern with weight iorder has been generated. + call nextpat101(misub,k,iorder,iflag) + enddo + enddo + + if(npre2.eq.1) then + reset=.true. + ntotal=0 + do i1=k,1,-1 + do i2=i1-1,1,-1 + ntotal=ntotal+1 + mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) + call boxit101(reset,mi(1:ntau),ntau,ntotal,i1,i2) + enddo + enddo + + ncount2=0 + ntotal2=0 + reset=.true. +! Now run through again and do the second pre-processing rule + misub(1:k-nord)=0 + misub(k-nord+1:k)=1 + iflag=k-nord+1 + do while(iflag .ge.0) + me=ieor(m0,misub) + call mrbencode101(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + do i2=0,ntau + ntotal2=ntotal2+1 + ui=0 + if(i2.gt.0) ui(i2)=1 + r2pat=ieor(e2sub,ui) +778 continue + call fetchit101(reset,r2pat(1:ntau),ntau,in1,in2) + if(in1.gt.0.and.in2.gt.0) then + ncount2=ncount2+1 + mi=misub + mi(in1)=1 + mi(in2)=1 + if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle + me=ieor(m0,mi) + call mrbencode101(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + dd=sum(nxor*absrx) + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + endif + goto 778 + endif + enddo + call nextpat101(misub,k,nord,iflag) + enddo + endif + +998 continue +! Re-order the codeword to [message bits][parity bits] format. + cw(indices)=cw + hdec(indices)=hdec + message101=cw(1:101) + call get_crc24(message101,101,nbadcrc) + if(nbadcrc.ne.0) nhardmin=-nhardmin + + return +end subroutine osd240_101 + +subroutine mrbencode101(me,codeword,g2,N,K) + integer*1 me(K),codeword(N),g2(N,K) +! fast encoding for low-weight test patterns + codeword=0 + do i=1,K + if( me(i) .eq. 1 ) then + codeword=ieor(codeword,g2(1:N,i)) + endif + enddo + return +end subroutine mrbencode101 + +subroutine nextpat101(mi,k,iorder,iflag) + integer*1 mi(k),ms(k) +! generate the next test error pattern + ind=-1 + do i=1,k-1 + if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i + enddo + if( ind .lt. 0 ) then ! no more patterns of this order + iflag=ind + return + endif + ms=0 + ms(1:ind-1)=mi(1:ind-1) + ms(ind)=1 + ms(ind+1)=0 + if( ind+1 .lt. k ) then + nz=iorder-sum(ms) + ms(k-nz+1:k)=1 + endif + mi=ms + do i=1,k ! iflag will point to the lowest-index 1 in mi + if(mi(i).eq.1) then + iflag=i + exit + endif + enddo + return +end subroutine nextpat101 + +subroutine boxit101(reset,e2,ntau,npindex,i1,i2) + integer*1 e2(1:ntau) + integer indexes(5000,2),fp(0:525000),np(5000) + logical reset + common/boxes/indexes,fp,np + + if(reset) then + patterns=-1 + fp=-1 + np=-1 + sc=-1 + indexes=-1 + reset=.false. + endif + + indexes(npindex,1)=i1 + indexes(npindex,2)=i2 + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + + ip=fp(ipat) ! see what's currently stored in fp(ipat) + if(ip.eq.-1) then + fp(ipat)=npindex + else + do while (np(ip).ne.-1) + ip=np(ip) + enddo + np(ip)=npindex + endif + return +end subroutine boxit101 + +subroutine fetchit101(reset,e2,ntau,i1,i2) + integer indexes(5000,2),fp(0:525000),np(5000) + integer lastpat + integer*1 e2(ntau) + logical reset + common/boxes/indexes,fp,np + save lastpat,inext + + if(reset) then + lastpat=-1 + reset=.false. + endif + + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + index=fp(ipat) + + if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices + i1=indexes(index,1) + i2=indexes(index,2) + inext=np(index) + elseif(lastpat.eq.ipat .and. inext.gt.0) then + i1=indexes(inext,1) + i2=indexes(inext,2) + inext=np(inext) + else + i1=-1 + i2=-1 + inext=-1 + endif + lastpat=ipat + return +end subroutine fetchit101 + diff --git a/lib/fst280/osd280_101.f90 b/lib/fst240/osd280_101.f90 similarity index 100% rename from lib/fst280/osd280_101.f90 rename to lib/fst240/osd280_101.f90 diff --git a/lib/fst280/osd280_74.f90 b/lib/fst240/osd280_74.f90 similarity index 100% rename from lib/fst280/osd280_74.f90 rename to lib/fst240/osd280_74.f90 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 new file mode 100644 index 000000000..231e00e84 --- /dev/null +++ b/lib/fst240_decode.f90 @@ -0,0 +1,554 @@ +module fst240_decode + + type :: fst240_decoder + procedure(fst240_decode_callback), pointer :: callback + contains + procedure :: decode + end type fst240_decoder + + abstract interface + subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & + decoded,nap,qual,ntrperiod) + import fst240_decoder + implicit none + class(fst240_decoder), intent(inout) :: this + integer, intent(in) :: nutc + real, intent(in) :: sync + integer, intent(in) :: nsnr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + integer, intent(in) :: ntrperiod + end subroutine fst240_decode_callback + end interface + +contains + + subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & + nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol) + + use timer_module, only: timer + use packjt77 + include 'fst240/fst240_params.f90' + parameter (MAXCAND=100) + class(fst240_decoder), intent(inout) :: this + procedure(fst240_decode_callback) :: callback + character*37 decodes(100) + character*37 msg + character*77 c77 + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real llr(240),llra(240),llrb(240),llrc(240),llrd(240) + real candidates(100,4) + real bitmetrics(320,4) + real s4(0:3,NN) + integer itone(NN) + integer hmod + integer*1 apmask(240),cw(240) + integer*1 hbits(320) + integer*1 message101(101),message74(74) + logical badsync,unpk77_success,single_decode + integer*2 iwave(300*12000) + + this%callback => callback + hmod=2**nsubmode + if(nfqso+nqsoprogress.eq.-999) return + Keff=91 + iwspr=0 + nmax=15*12000 + single_decode=iand(nexp_decode,32).eq.32 + if(ntrperiod.eq.15) then + nsps=800 + nmax=15*12000 + ndown=20/hmod !nss=40,80,160,400 + if(hmod.eq.8) ndown=2 + else if(ntrperiod.eq.30) then + nsps=1680 + nmax=30*12000 + ndown=42/hmod !nss=40,80,168,336 + if(hmod.eq.4) ndown=10 + if(hmod.eq.8) ndown=5 + else if(ntrperiod.eq.60) then + nsps=3888 + nmax=60*12000 + ndown=96/hmod !nss=36,81,162,324 + if(hmod.eq.1) ndown=108 + else if(ntrperiod.eq.120) then + nsps=8200 + nmax=120*12000 + ndown=200/hmod !nss=40,82,164,328 + if(hmod.eq.1) ndown=205 + else if(ntrperiod.eq.300) then + nsps=21504 + nmax=300*12000 + ndown=512/hmod !nss=42,84,168,336 + end if + nss=nsps/ndown + fs=12000.0 !Sample rate + fs2=fs/ndown + nspsec=nint(fs2) + dt=1.0/fs !Sample interval (s) + dt2=1.0/fs2 + tt=nsps*dt !Duration of "itone" symbols (s) + baud=1.0/tt + nfft1=2*int(nmax/2) + nh1=nfft1/2 + allocate( r_data(1:nfft1+2) ) + allocate( c_bigfft(0:nfft1/2) ) + + nfft2=nfft1/ndown + allocate( c2(0:nfft2-1) ) + allocate( cframe(0:164*nss-1) ) + + npts=nmax + if(single_decode) then + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) + else + fa=max(100,nfa) + fb=min(4800,nfb) + endif + + if(ndeep.eq.3) then + ntmax=4 ! number of block sizes to try + jittermax=2 + norder=3 + elseif(ndeep.eq.2) then + ntmax=3 + jittermax=2 + norder=3 + elseif(ndeep.eq.1) then + ntmax=1 + jittermax=2 + norder=2 + endif + + ! The big fft is done once and is used for calculating the smoothed spectrum +! and also for downconverting/downsampling each candidate. + r_data(1:nfft1)=iwave(1:nfft1) + r_data(nfft1+1:nfft1+2)=0.0 + call four2a(r_data,nfft1,1,-1,0) + c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + +! Get first approximation of candidate frequencies + call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + ncand,candidates,base) + + ndecodes=0 + decodes=' ' + + isbest1=0 + isbest8=0 + fc21=0. + fc28=0. + do icand=1,ncand + fc0=candidates(icand,1) + detmet=candidates(icand,2) + +! Downconvert and downsample a slice of the spectrum centered on the +! rough estimate of the candidates frequency. +! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. +! The size of the downsampled c2 array is nfft2=nfft1/ndown + + call fst240_downsample(c_bigfft,nfft1,ndown,fc0,c2) + + call timer('sync240 ',0) + do isync=0,1 + if(isync.eq.0) then + fc1=0.0 + is0=1.5*nint(fs2) + ishw=1.5*is0 + isst=4*hmod + ifhw=12 + df=.1*baud + else if(isync.eq.1) then + fc1=fc21 + if(hmod.eq.1) fc1=fc28 + is0=isbest1 + if(hmod.eq.1) is0=isbest8 + ishw=4*hmod + isst=1*hmod + ifhw=7 + df=.02*baud + endif + + smax1=0.0 + smax8=0.0 + do if=-ifhw,ifhw + fc=fc1+df*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) + call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) + if(sync8.gt.smax8) then + fc28=fc + isbest8=istart + smax8=sync8 + endif + if(sync1.gt.smax1) then + fc21=fc + isbest1=istart + smax1=sync1 + endif + enddo + enddo + enddo + call timer('sync240 ',1) + + if(smax8/smax1 .lt. 0.65 ) then + fc2=fc21 + isbest=isbest1 + if(hmod.gt.1) ntmax=1 + njitter=2 + else + fc2=fc28 + isbest=isbest8 + if(hmod.gt.1) ntmax=1 + njitter=2 + endif + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + candidates(icand,3)=fc_synced + candidates(icand,4)=isbest + enddo +! remove duplicate candidates + do icand=1,ncand + fc=candidates(icand,3) + isbest=nint(candidates(icand,4)) + do ic2=1,ncand + fc2=candidates(ic2,3) + isbest2=nint(candidates(ic2,4)) + if(ic2.ne.icand .and. fc2.gt.0.0) then + if(abs(fc2-fc).lt.0.05*baud) then ! same frequency + if(abs(isbest2-isbest).le.2) then + candidates(ic2,3)=-1 + endif + endif + endif + enddo + enddo + + ic=0 + do icand=1,ncand + if(candidates(icand,3).gt.0) then + ic=ic+1 + candidates(ic,:)=candidates(icand,:) + endif + enddo + ncand=ic + do icand=1,ncand + sync=candidates(icand,2) + fc_synced=candidates(icand,3) + isbest=nint(candidates(icand,4)) + xdt=(isbest-nspsec)/fs2 + call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) + + do ijitter=0,jittermax + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+164*nss-1) + bitmetrics=0 + call get_fst240_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,s4,badsync) + if(badsync) cycle + + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5 + if(nsync_qual.lt. 26) cycle !### Value ?? ### + + scalefac=2.83 + llra( 1: 60)=bitmetrics( 17: 76, 1) + llra( 61:120)=bitmetrics( 93:152, 1) + llra(121:180)=bitmetrics(169:228, 1) + llra(181:240)=bitmetrics(245:304, 1) + llra=scalefac*llra + llrb( 1: 60)=bitmetrics( 17: 76, 2) + llrb( 61:120)=bitmetrics( 93:152, 2) + llrb(121:180)=bitmetrics(169:228, 2) + llrb(181:240)=bitmetrics(245:304, 2) + llrb=scalefac*llrb + llrc( 1: 60)=bitmetrics( 17: 76, 3) + llrc( 61:120)=bitmetrics( 93:152, 3) + llrc(121:180)=bitmetrics(169:228, 3) + llrc(181:240)=bitmetrics(245:304, 3) + llrc=scalefac*llrc + llrd( 1: 60)=bitmetrics( 17: 76, 4) + llrd( 61:120)=bitmetrics( 93:152, 4) + llrd(121:180)=bitmetrics(169:228, 4) + llrd(181:240)=bitmetrics(245:304, 4) + llrd=scalefac*llrd + apmask=0 + + do itry=1,ntmax + if(itry.eq.1) llr=llra + if(itry.eq.2) llr=llrb + if(itry.eq.3) llr=llrc + if(itry.eq.4) llr=llrd + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iwspr.eq.0) then + maxosd=2 + call timer('d240_101',0) + call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & + cw,ntype,nharderrors,dmin) + call timer('d240_101',1) + else + maxosd=2 + call timer('d240_74 ',0) +! call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & +! ntype,nharderrors,dmin) + call timer('d240_74 ',1) + endif + if(nharderrors .ge.0) then + if(iwspr.eq.0) then + write(c77,'(77i1)') message101(1:77) + call unpack77(c77,0,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,0,msg,unpk77_success) + endif + if(unpk77_success) then + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.msg) idupe=1 + enddo + if(idupe.eq.1) exit + ndecodes=ndecodes+1 + decodes(ndecodes)=msg + if(iwspr.eq.0) then + call get_fst240_tones_from_bits(message101,itone,iwspr) + xsig=0 + do i=1,NN + xsig=xsig+s4(itone(i),i)**2 + enddo + arg=400.0*(xsig/base)-1.0 + if(arg.gt.0.0) then + xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) + else + xsnr=-99.9 + endif + endif + nsnr=nint(xsnr) + iaptype=0 + qual=0. + fsig=fc_synced - 1.5*hmod*baud +write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & + nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg + call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & + iaptype,qual,ntrperiod) + goto 2002 + else + cycle + endif + endif + enddo ! metrics + enddo ! istart jitter +2002 continue + enddo !candidate list!ws + + return + end subroutine decode + + subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + +! Compute sync power for a complex, downsampled FST240 signal. + + include 'fst240/fst240_params.f90' + complex cd0(0:np-1) + complex, allocatable, save :: csync(:) + complex, allocatable, save :: csynct(:) + complex ctwk(8*nss) + complex z1,z2,z3,z4,z5 + logical first + integer hmod,isyncword(0:7) + real f0save + data isyncword/0,1,3,2,1,0,2,3/ + data first/.true./,f0save/0.0/,nss0/-1/ + save first,twopi,dt,fac,f0save,nss0 + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power + + if(nss.ne.nss0 .and. allocated(csync)) deallocate(csync,csynct) + if(first .or. nss.ne.nss0) then + allocate( csync(8*nss) ) + allocate( csynct(8*nss) ) + twopi=8.0*atan(1.0) + dt=1/fs + k=1 + phi=0.0 + do i=0,7 + dphi=twopi*hmod*(isyncword(i)-1.5)/real(nss) + do j=1,nss + csync(k)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + k=k+1 + enddo + enddo + first=.false. + nss0=nss + fac=1.0/(8.0*nss) + endif + + if(f0.ne.f0save) then + dphi=twopi*f0*dt + phi=0.0 + do i=1,8*nss + ctwk(i)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + enddo + csynct=ctwk*csync + f0save=f0 + endif + + i1=i0 !Costas arrays + i2=i0+38*nss + i3=i0+76*nss + i4=i0+114*nss + i5=i0+152*nss + + s1=0.0 + s2=0.0 + s3=0.0 + s4=0.0 + s5=0.0 + + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=0 + if(i1+is.ge.1) then + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + endif + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z5=0 + if(i5+is+ncoh*nss-1.le.np) then + z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + endif + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + s4=s4+abs(z4)/(8*nss) + s5=s5+abs(z5)/(8*nss) + enddo + + sync = s1+s2+s3+s4+s5 + + return + end subroutine sync_fst240 + + subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,c1) + +! Output: Complex data in c(), sampled at 12000/ndown Hz + + complex c_bigfft(0:nfft1/2) + complex c1(0:nfft1/ndown-1) + + df=12000.0/nfft1 + i0=nint(f0/df) + c1(0)=c_bigfft(i0) + nfft2=nfft1/ndown + do i=1,nfft2/2 + if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) + if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) + enddo + c1=c1/nfft2 + call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain + return + + end subroutine fst240_downsample + + subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + ncand,candidates,base) + + complex c_bigfft(0:nfft1/2) + integer hmod + integer indx(100) + real candidates(100,4) + real candidates0(100,4) + real snr_cand(100) + real s(18000) + real s2(18000) + data nfft1z/-1/ + save nfft1z + + nh1=nfft1/2 + df1=fs/nfft1 + baud=fs/nsps + df2=baud/2.0 + nd=df2/df1 + ndh=nd/2 + ia=nint(max(100.0,fa)/df2) + ib=nint(min(4800.0,fb)/df2) + signal_bw=4*(12000.0/nsps)*hmod + analysis_bw=min(4800.0,fb)-max(100.0,fa) + noise_bw=10.0*signal_bw + if(analysis_bw.gt.noise_bw) then + ina=ia + inb=ib + else + fcenter=(fa+fb)/2.0 + fl = max(100.0,fcenter-noise_bw/2.)/df2 + fh = min(4800.0,fcenter+noise_bw/2.)/df2 + ina=nint(fl) + inb=nint(fh) + endif + s=0. + do i=ina,inb ! noise analysis window includes signal analysis window + j0=nint(i*df2/df1) + do j=j0-ndh,j0+ndh + s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + enddo + enddo + ina=max(ina,1+3*hmod) + inb=min(inb,18000-3*hmod) + s2=0. + do i=ina,inb + s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) + enddo + call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) + s2=s2/base + thresh=1.25 + + ncand=0 + candidates=0 + if(ia.lt.3) ia=3 + if(ib.gt.18000-2) ib=18000-2 + do i=ia,ib + if((s2(i).gt.s2(i-2)).and. & + (s2(i).gt.s2(i+2)).and. & + (s2(i).gt.thresh).and.ncand.lt.100) then + ncand=ncand+1 + candidates(ncand,1)=df2*i + candidates(ncand,2)=s2(i) + endif + enddo + + snr_cand=0. + snr_cand(1:ncand)=candidates(1:ncand,2) + call indexx(snr_cand,ncand,indx) + nmax=min(ncand,20) + do i=1,nmax + j=indx(ncand+1-i) + candidates0(i,1:4)=candidates(j,1:4) + enddo + ncand=nmax + candidates(1:ncand,1:4)=candidates0(1:ncand,1:4) + candidates(ncand+1:,1:4)=0. + return + end subroutine get_candidates_fst240 + +end module fst240_decode diff --git a/lib/jt9.f90 b/lib/jt9.f90 index afd5c374e..23f330c9f 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -54,7 +54,7 @@ program jt9 option ('jt4', .false., '4', 'JT4 mode', ''), & option ('ft4', .false., '5', 'FT4 mode', ''), & option ('jt65', .false.,'6', 'JT65 mode', ''), & - option ('fst280', .false., '7', 'FT8 mode', ''), & + option ('fst240', .false., '7', 'FT8 mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & @@ -124,7 +124,7 @@ program jt9 case ('6') if (mode.lt.65) mode = mode + 65 case ('7') - mode = 280 + mode = 240 case ('8') mode = 8 case ('9') @@ -235,7 +235,7 @@ program jt9 call timer('symspec ',1) endif nhsym0=nhsym - if(nhsym.ge.181 .and. mode.ne.280) exit + if(nhsym.ge.181 .and. mode.ne.240) exit endif enddo close(unit=wav%lun) @@ -250,7 +250,7 @@ program jt9 shared_data%params%nfb=fhigh shared_data%params%ntol=20 shared_data%params%kin=64800 - if(mode.eq.280) shared_data%params%kin=720000 !### 60 s periods ### + if(mode.eq.240) shared_data%params%kin=720000 !### 60 s periods ### shared_data%params%nzhsym=nhsym shared_data%params%ndepth=ndepth shared_data%params%lft8apon=.true. diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index def2e6ec4..056950611 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -46,21 +46,21 @@ namespace {20000000, Modes::FreqCal, IARURegions::ALL}, {136000, Modes::WSPR, IARURegions::ALL}, - {136000, Modes::FST280W, IARURegions::ALL}, + {136000, Modes::FST240W, IARURegions::ALL}, {136130, Modes::JT65, IARURegions::ALL}, {136130, Modes::JT9, IARURegions::ALL}, - {136130, Modes::FST280, IARURegions::ALL}, + {136130, Modes::FST240, IARURegions::ALL}, {474200, Modes::JT65, IARURegions::ALL}, {474200, Modes::JT9, IARURegions::ALL}, - {474200, Modes::FST280, IARURegions::ALL}, + {474200, Modes::FST240, IARURegions::ALL}, {474200, Modes::WSPR, IARURegions::ALL}, - {474200, Modes::FST280W, IARURegions::ALL}, + {474200, Modes::FST240W, IARURegions::ALL}, {1836600, Modes::WSPR, IARURegions::ALL}, {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations {1839000, Modes::JT9, IARURegions::ALL}, - {1839000, Modes::FST280, IARURegions::ALL}, + {1839000, Modes::FST240, IARURegions::ALL}, {1840000, Modes::FT8, IARURegions::ALL}, // Band plans (all USB dial unless stated otherwise) @@ -92,7 +92,7 @@ namespace // {3570000, Modes::JT65, IARURegions::ALL}, // JA compatible {3572000, Modes::JT9, IARURegions::ALL}, - {3572000, Modes::FST280, IARURegions::ALL}, + {3572000, Modes::FST240, IARURegions::ALL}, {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out {3575000, Modes::FT4, IARURegions::ALL}, // provisional @@ -133,7 +133,7 @@ namespace {7074000, Modes::FT8, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL}, - {7078000, Modes::FST280, IARURegions::ALL}, + {7078000, Modes::FST240, IARURegions::ALL}, {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved // up 500Hz to clear // W1AW code practice QRG @@ -168,7 +168,7 @@ namespace {10138000, Modes::JT65, IARURegions::ALL}, {10138700, Modes::WSPR, IARURegions::ALL}, {10140000, Modes::JT9, IARURegions::ALL}, - {10140000, Modes::FST280, IARURegions::ALL}, + {10140000, Modes::FST240, IARURegions::ALL}, {10140000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -212,7 +212,7 @@ namespace {14074000, Modes::FT8, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL}, - {14078000, Modes::FST280, IARURegions::ALL}, + {14078000, Modes::FST240, IARURegions::ALL}, {14080000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -245,28 +245,28 @@ namespace {18100000, Modes::FT8, IARURegions::ALL}, {18102000, Modes::JT65, IARURegions::ALL}, {18104000, Modes::JT9, IARURegions::ALL}, - {18104000, Modes::FST280, IARURegions::ALL}, + {18104000, Modes::FST240, IARURegions::ALL}, {18104000, Modes::FT4, IARURegions::ALL}, // provisional {18104600, Modes::WSPR, IARURegions::ALL}, {21074000, Modes::FT8, IARURegions::ALL}, {21076000, Modes::JT65, IARURegions::ALL}, {21078000, Modes::JT9, IARURegions::ALL}, - {21078000, Modes::FST280, IARURegions::ALL}, + {21078000, Modes::FST240, IARURegions::ALL}, {21094600, Modes::WSPR, IARURegions::ALL}, {21140000, Modes::FT4, IARURegions::ALL}, {24915000, Modes::FT8, IARURegions::ALL}, {24917000, Modes::JT65, IARURegions::ALL}, {24919000, Modes::JT9, IARURegions::ALL}, - {24919000, Modes::FST280, IARURegions::ALL}, + {24919000, Modes::FST240, IARURegions::ALL}, {24919000, Modes::FT4, IARURegions::ALL}, // provisional {24924600, Modes::WSPR, IARURegions::ALL}, {28074000, Modes::FT8, IARURegions::ALL}, {28076000, Modes::JT65, IARURegions::ALL}, {28078000, Modes::JT9, IARURegions::ALL}, - {28078000, Modes::FST280, IARURegions::ALL}, + {28078000, Modes::FST240, IARURegions::ALL}, {28124600, Modes::WSPR, IARURegions::ALL}, {28180000, Modes::FT4, IARURegions::ALL}, @@ -280,7 +280,7 @@ namespace {50293000, Modes::WSPR, IARURegions::R3}, {50310000, Modes::JT65, IARURegions::ALL}, {50312000, Modes::JT9, IARURegions::ALL}, - {50312000, Modes::FST280, IARURegions::ALL}, + {50312000, Modes::FST240, IARURegions::ALL}, {50313000, Modes::FT8, IARURegions::ALL}, {50318000, Modes::FT4, IARURegions::ALL}, // provisional {50323000, Modes::FT8, IARURegions::ALL}, diff --git a/models/Modes.hpp b/models/Modes.hpp index c98b1c6fb..deb22865f 100644 --- a/models/Modes.hpp +++ b/models/Modes.hpp @@ -50,8 +50,8 @@ public: FreqCal, FT8, FT4, - FST280, - FST280W, + FST240, + FST240W, MODES_END_SENTINAL_AND_COUNT // this must be last }; Q_ENUM (Mode) diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 47478e346..5d8136a01 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -460,7 +460,7 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx if(modeTx=="JT4") t1=" $ "; if(modeTx=="JT65") t1=" # "; if(modeTx=="MSK144") t1=" & "; - if(modeTx=="FST280") t1=" ` "; + if(modeTx=="FST240") t1=" ` "; QString t2; t2 = t2.asprintf("%4d",txFreq); QString t; diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 4ac9f485c..40c94143d 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -105,7 +105,7 @@ extern "C" { void genft4_(char* msg, int* ichk, char* msgsent, char ft4msgbits[], int itone[], fortran_charlen_t, fortran_charlen_t); - void genfst280_(char* msg, int* ichk, char* msgsent, char fst280msgbits[], + void genfst240_(char* msg, int* ichk, char* msgsent, char fst240msgbits[], int itone[], int* iwspr, fortran_charlen_t, fortran_charlen_t); void gen_ft8wave_(int itone[], int* nsym, int* nsps, float* bt, float* fsample, float* f0, @@ -114,7 +114,7 @@ extern "C" { void gen_ft4wave_(int itone[], int* nsym, int* nsps, float* fsample, float* f0, float xjunk[], float wave[], int* icmplx, int* nwave); - void gen_fst280wave_(int itone[], int* nsym, int* nsps, int* nwave, float* fsample, + void gen_fst240wave_(int itone[], int* nsym, int* nsps, int* nwave, float* fsample, int* hmod, float* f0, int* icmplx, float xjunk[], float wave[]); void gen4_(char* msg, int* ichk, char* msgsent, int itone[], @@ -429,7 +429,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); - ui->sbTR_FST280W->values ({120, 300}); + ui->sbTR_FST240W->values ({120, 300}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -580,8 +580,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, on_EraseButton_clicked (); QActionGroup* modeGroup = new QActionGroup(this); - ui->actionFST280->setActionGroup(modeGroup); - ui->actionFST280W->setActionGroup(modeGroup); + ui->actionFST240->setActionGroup(modeGroup); + ui->actionFST240W->setActionGroup(modeGroup); ui->actionFT4->setActionGroup(modeGroup); ui->actionFT8->setActionGroup(modeGroup); ui->actionJT9->setActionGroup(modeGroup); @@ -1341,7 +1341,7 @@ void MainWindow::fixStop() m_hsymStop=50; } else if (m_mode=="FT4") { m_hsymStop=21; - } else if(m_mode=="FST280" or m_mode=="FST280W") { + } else if(m_mode=="FST240" or m_mode=="FST240W") { int stop[] = {45,87,192,397,1012}; int stop_EME[] = {51,96,201,406,1021}; int i=0; @@ -2313,9 +2313,9 @@ void MainWindow::setup_status_bar (bool vhf) mode_label.setStyleSheet ("QLabel{background-color: #ff0099}"); } else if ("FT8" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff6699}"); - } else if ("FST280" == m_mode) { + } else if ("FST240" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #99ff66}"); - } else if ("FST280W" == m_mode) { + } else if ("FST240W" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #6699ff}"); } else if ("FreqCal" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff9933}"); @@ -2898,7 +2898,7 @@ void MainWindow::decode() //decode() dec_data.params.nutc=100*ihr + imin; if(m_TRperiod < 60) { qint64 ms=1000.0*(2.0-m_TRperiod); - if(m_mode=="FST280") ms=1000.0*(6.0-m_TRperiod); + if(m_mode=="FST240") ms=1000.0*(6.0-m_TRperiod); //Adjust for FT8 early decode: if(m_mode=="FT8" and m_ihsym==m_earlyDecode and !m_diskData) ms+=(m_hsymStop-m_earlyDecode)*288; if(m_mode=="FT8" and m_ihsym==m_earlyDecode2 and !m_diskData) ms+=(m_hsymStop-m_earlyDecode2)*288; @@ -2968,7 +2968,7 @@ void MainWindow::decode() //decode() dec_data.params.nmode=5; m_BestCQpriority=""; } - if(m_mode=="FST280") dec_data.params.nmode=280; + if(m_mode=="FST240") dec_data.params.nmode=240; dec_data.params.ntrperiod=m_TRperiod; dec_data.params.nsubmode=m_nSubMode; if(m_mode=="QRA64") dec_data.params.nsubmode=100 + m_nSubMode; @@ -3250,7 +3250,7 @@ void MainWindow::readFromStdout() //readFromStdout //Right (Rx Frequency) window bool bDisplayRight=bAvgMsg; int audioFreq=decodedtext.frequencyOffset(); - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") { + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") { auto const& parts = decodedtext.string().remove("<").remove(">") .split (' ', SkipEmptyParts); if (parts.size() > 6) { @@ -3334,7 +3334,7 @@ void MainWindow::readFromStdout() //readFromStdout //### I think this is where we are preventing Hounds from spotting Fox ### if(m_mode!="FT8" or (SpecOp::HOUND != m_config.special_op_id())) { if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="QRA64" or m_mode=="JT4" - or m_mode=="JT65" or m_mode=="JT9" or m_mode=="FST280") { + or m_mode=="JT65" or m_mode=="JT9" or m_mode=="FST240") { auto_sequence (decodedtext, 25, 50); } @@ -3537,7 +3537,7 @@ void MainWindow::guiUpdate() if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65 if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR - if(m_modeTx=="FST280" or m_mode=="FST280W") { //FST280, FST280W + if(m_modeTx=="FST240" or m_mode=="FST240W") { //FST240, FST240W if(m_TRperiod==15) txDuration=1.0 + 166*800/12000.0; if(m_TRperiod==30) txDuration=1.0 + 166*1680/12000.0; if(m_TRperiod==60) txDuration=1.0 + 166*3888/12000.0; @@ -3815,7 +3815,7 @@ void MainWindow::guiUpdate() if(m_modeTx=="WSPR") genwspr_(message, msgsent, const_cast (itone), 22, 22); if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4" - or m_modeTx=="FST280" or m_modeTx=="FST280W") { + or m_modeTx=="FST240" or m_modeTx=="FST240W") { char MyCall[6]; char MyGrid[6]; ::memcpy(MyCall, (m_config.my_callsign()+" ").toLatin1(), sizeof MyCall); @@ -3875,11 +3875,11 @@ void MainWindow::guiUpdate() gen_ft4wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave, foxcom_.wave,&icmplx,&nwave); } - if(m_modeTx=="FST280" or m_modeTx=="FST280W") { + if(m_modeTx=="FST240" or m_modeTx=="FST240W") { int ichk=0; int iwspr=0; - char fst280msgbits[101]; - genfst280_(message,&ichk,msgsent,const_cast (fst280msgbits), + char fst240msgbits[101]; + genfst240_(message,&ichk,msgsent,const_cast (fst240msgbits), const_cast(itone), &iwspr, 37, 37); int hmod=int(pow(2.0,double(m_nSubMode))); int nsps=800; @@ -3895,7 +3895,7 @@ void MainWindow::guiUpdate() // int nwave=(nsym+2)*nsps; int nwave=48000 + 166*nsps; int icmplx=0; - gen_fst280wave_(const_cast(itone),&nsym,&nsps,&nwave, + gen_fst240wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); } @@ -5813,16 +5813,16 @@ void MainWindow::displayWidgets(qint64 n) genStdMsgs (m_rpt, true); } -void MainWindow::on_actionFST280_triggered() +void MainWindow::on_actionFST240_triggered() { int nsub=m_nSubMode; on_actionJT65_triggered(); ui->sbSubmode->setMaximum(3); m_nSubMode=nsub; ui->sbSubmode->setValue(m_nSubMode); - m_mode="FST280"; - m_modeTx="FST280"; - ui->actionFST280->setChecked(true); + m_mode="FST240"; + m_modeTx="FST240"; + ui->actionFST240->setChecked(true); WSPR_config(false); bool bVHF=m_config.enable_VHF_features(); // 012345678901234567890123456789012 @@ -5835,16 +5835,16 @@ void MainWindow::on_actionFST280_triggered() ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); - switch_mode (Modes::FST280); + switch_mode (Modes::FST240); statusChanged(); } -void MainWindow::on_actionFST280W_triggered() +void MainWindow::on_actionFST240W_triggered() { - m_mode="FST280W"; - m_modeTx="FST280W"; + m_mode="FST240W"; + m_modeTx="FST240W"; WSPR_config(true); - ui->actionFST280W->setChecked(true); + ui->actionFST240W->setChecked(true); // 012345678901234567890123456789012 displayWidgets(nWidgets("000001000000000001010000000000000")); bool bVHF=m_config.enable_VHF_features(); @@ -5856,7 +5856,7 @@ void MainWindow::on_actionFST280W_triggered() ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); - switch_mode (Modes::FST280W); + switch_mode (Modes::FST240W); statusChanged(); } @@ -7163,7 +7163,7 @@ void MainWindow::transmit (double snr) true, false, snr, m_TRperiod); } - if (m_modeTx == "FST280" or m_modeTx == "FST280W") { + if (m_modeTx == "FST240" or m_modeTx == "FST240W") { m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. int nsps=800; @@ -7174,7 +7174,7 @@ void MainWindow::transmit (double snr) int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; - Q_EMIT sendMessage (NUM_FST280_SYMBOLS,double(nsps),f0,toneSpacing, + Q_EMIT sendMessage (NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); } @@ -7430,7 +7430,7 @@ void::MainWindow::VHF_features_enabled(bool b) void MainWindow::on_sbTR_valueChanged(int value) { // if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode; - if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST280" or m_mode=="FST280W") { + if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST240" or m_mode=="FST240W") { m_TRperiod = value; m_fastGraph->setTRPeriod (value); m_modulator->setTRPeriod (value); // TODO - not thread safe @@ -8254,7 +8254,7 @@ void MainWindow::on_cbFirst_toggled(bool b) void MainWindow::on_cbAutoSeq_toggled(bool b) { if(!b) ui->cbFirst->setChecked(false); - ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") and b); + ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") and b); } void MainWindow::on_measure_check_box_stateChanged (int state) @@ -9031,8 +9031,8 @@ void MainWindow::on_pbBestSP_clicked() void MainWindow::set_mode (QString const& mode) { if ("FT4" == mode) on_actionFT4_triggered (); - else if ("FST280" == mode) on_actionFST280_triggered (); - else if ("FST280W" == mode) on_actionFST280W_triggered (); + else if ("FST240" == mode) on_actionFST240_triggered (); + else if ("FST240W" == mode) on_actionFST240W_triggered (); else if ("FT8" == mode) on_actionFT8_triggered (); else if ("JT4" == mode) on_actionJT4_triggered (); else if ("JT9" == mode) on_actionJT9_triggered (); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index b342850bd..157141cdd 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -49,7 +49,7 @@ #define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync #define NUM_FT8_SYMBOLS 79 #define NUM_FT4_SYMBOLS 105 -#define NUM_FST280_SYMBOLS 166 //280/2 data + 6*4 sync + 2 ramp +#define NUM_FST240_SYMBOLS 160 //240/2 data + 5*8 sync #define NUM_CW_SYMBOLS 250 #define TX_SAMPLE_RATE 48000 #define N_WIDGETS 33 @@ -205,8 +205,8 @@ private slots: void on_actionJT4_triggered(); void on_actionFT4_triggered(); void on_actionFT8_triggered(); - void on_actionFST280_triggered(); - void on_actionFST280W_triggered(); + void on_actionFST240_triggered(); + void on_actionFST240W_triggered(); void on_TxFreqSpinBox_valueChanged(int arg1); void on_actionSave_decoded_triggered(); void on_actionQuickDecode_toggled (bool); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 9b07c7714..b635ee21a 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2591,7 +2591,7 @@ list. The list can be maintained in Settings (F2). - + Qt::AlignCenter @@ -2861,8 +2861,8 @@ list. The list can be maintained in Settings (F2). Mode - - + + @@ -3497,30 +3497,30 @@ list. The list can be maintained in Settings (F2). FT4 - + true - FST280 + FST240 - + - FST280-W + FST240-W - + - FT280W + FT240W - + true - FST280W + FST240W diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 947f6a0e5..5ac16038c 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -414,7 +414,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() float bw=9.0*12000.0/m_nsps; //JT9 if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 - if(m_mode=="FST280") { + if(m_mode=="FST240") { int h=int(pow(2.0,m_nSubMode)); int nsps=800; if(m_TRperiod==30) nsps=1680; @@ -500,7 +500,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() int yTxTop=12; int yRxBottom=yTxTop + 2*yh + 4; if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" - or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST280") { + or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") { if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) { painter0.setPen(penGreen); @@ -531,7 +531,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,yRxBottom-yh,x1,yRxBottom); painter0.drawLine(x1,yRxBottom,x2,yRxBottom); painter0.drawLine(x2,yRxBottom-yh,x2,yRxBottom); - if(m_mode=="FST280") { + if(m_mode=="FST240") { x1=XfromFreq(m_rxFreq-m_tol); x2=XfromFreq(m_rxFreq+m_tol); painter0.drawLine(x1,26,x2,26); // Mark the Tol range @@ -542,7 +542,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8" - or m_mode=="FT4" or m_mode=="FST280") { + or m_mode=="FT4" or m_mode=="FST240") { painter0.setPen(penRed); x1=XfromFreq(m_txFreq); x2=XfromFreq(m_txFreq+bw); From 3cb1980ef1b730e0a36680f4ccd0b2df860d6c89 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 27 Jun 2020 09:21:43 -0500 Subject: [PATCH 075/239] Remove un-needed files. --- lib/fst240/bpdecode280_101.f90 | 111 ------ lib/fst240/bpdecode280_74.f90 | 111 ------ lib/fst240/decode280_101.f90 | 154 -------- lib/fst240/decode280_74.f90 | 153 -------- lib/fst240/encode280_101.f90 | 40 -- lib/fst240/encode280_74.f90 | 40 -- lib/fst240/fst280.txt | 10 - lib/fst240/fst280_params.f90 | 8 - lib/fst240/fst280d.f90 | 481 ------------------------ lib/fst240/fst280sim.f90 | 143 -------- lib/fst240/gen_fst280wave.f90 | 98 ----- lib/fst240/genfst280.f90 | 109 ------ lib/fst240/get_fst280_bitmetrics.f90 | 120 ------ lib/fst240/ldpc_280_101_generator.f90 | 182 ---------- lib/fst240/ldpc_280_101_parity.f90 | 476 ------------------------ lib/fst240/ldpc_280_74_generator.f90 | 209 ----------- lib/fst240/ldpc_280_74_parity.f90 | 504 -------------------------- lib/fst240/ldpcsim280_101.f90 | 139 ------- lib/fst240/ldpcsim280_74.f90 | 132 ------- lib/fst240/osd280_101.f90 | 403 -------------------- lib/fst240/osd280_74.f90 | 403 -------------------- 21 files changed, 4026 deletions(-) delete mode 100644 lib/fst240/bpdecode280_101.f90 delete mode 100644 lib/fst240/bpdecode280_74.f90 delete mode 100644 lib/fst240/decode280_101.f90 delete mode 100644 lib/fst240/decode280_74.f90 delete mode 100644 lib/fst240/encode280_101.f90 delete mode 100644 lib/fst240/encode280_74.f90 delete mode 100644 lib/fst240/fst280.txt delete mode 100644 lib/fst240/fst280_params.f90 delete mode 100644 lib/fst240/fst280d.f90 delete mode 100644 lib/fst240/fst280sim.f90 delete mode 100644 lib/fst240/gen_fst280wave.f90 delete mode 100644 lib/fst240/genfst280.f90 delete mode 100644 lib/fst240/get_fst280_bitmetrics.f90 delete mode 100644 lib/fst240/ldpc_280_101_generator.f90 delete mode 100644 lib/fst240/ldpc_280_101_parity.f90 delete mode 100644 lib/fst240/ldpc_280_74_generator.f90 delete mode 100644 lib/fst240/ldpc_280_74_parity.f90 delete mode 100644 lib/fst240/ldpcsim280_101.f90 delete mode 100644 lib/fst240/ldpcsim280_74.f90 delete mode 100644 lib/fst240/osd280_101.f90 delete mode 100644 lib/fst240/osd280_74.f90 diff --git a/lib/fst240/bpdecode280_101.f90 b/lib/fst240/bpdecode280_101.f90 deleted file mode 100644 index a817a3d5c..000000000 --- a/lib/fst240/bpdecode280_101.f90 +++ /dev/null @@ -1,111 +0,0 @@ -subroutine bpdecode280_101(llr,apmask,maxiterations,message101,cw,nharderror,iter,ncheck) -! -! A log-domain belief propagation decoder for the (280,101) code. -! - integer, parameter:: N=280, K=101, M=N-K - integer*1 cw(N),apmask(N) - integer*1 decoded(K) - integer*1 message101(101) - integer nrw(M),ncw - integer Nm(6,M) - integer Mn(3,N) ! 3 checks per bit - integer synd(M) - real tov(3,N) - real toc(6,M) - real tanhtoc(6,M) - real zn(N) - real llr(N) - real Tmn - - include "ldpc_280_101_parity.f90" - - decoded=0 - toc=0 - tov=0 - tanhtoc=0 -! initialize messages to checks - do j=1,M - do i=1,nrw(j) - toc(i,j)=llr((Nm(i,j))) - enddo - enddo - - ncnt=0 - nclast=0 - do iter=0,maxiterations -! Update bit log likelihood ratios (tov=0 in iteration 0). - do i=1,N - if( apmask(i) .ne. 1 ) then - zn(i)=llr(i)+sum(tov(1:ncw,i)) - else - zn(i)=llr(i) - endif - enddo - -! Check to see if we have a codeword (check before we do any iteration). - cw=0 - where( zn .gt. 0. ) cw=1 - ncheck=0 - do i=1,M - synd(i)=sum(cw(Nm(1:nrw(i),i))) - if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 -! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied' - enddo - if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it - decoded=cw(1:101) - call get_crc24(decoded,101,nbadcrc) - nharderror=count( (2*cw-1)*llr .lt. 0.0 ) - if(nbadcrc.eq.0) then - message101=decoded(1:101) - return - endif - endif - - if( iter.gt.0 ) then ! this code block implements an early stopping criterion -! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion - nd=ncheck-nclast - if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased - ncnt=0 ! reset counter - else - ncnt=ncnt+1 - endif -! write(*,*) iter,ncheck,nd,ncnt - if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then - nharderror=-1 - return - endif - endif - nclast=ncheck - -! Send messages from bits to check nodes - do j=1,M - do i=1,nrw(j) - ibj=Nm(i,j) - toc(i,j)=zn(ibj) - do kk=1,ncw ! subtract off what the bit had received from the check - if( Mn(kk,ibj) .eq. j ) then - toc(i,j)=toc(i,j)-tov(kk,ibj) - endif - enddo - enddo - enddo - -! send messages from check nodes to variable nodes - do i=1,M - tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2) - enddo - - do j=1,N - do i=1,ncw - ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j - Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) - call platanh(-Tmn,y) -! y=atanh(-Tmn) - tov(i,j)=2*y - enddo - enddo - - enddo - nharderror=-1 - return -end subroutine bpdecode280_101 diff --git a/lib/fst240/bpdecode280_74.f90 b/lib/fst240/bpdecode280_74.f90 deleted file mode 100644 index 21b48d8db..000000000 --- a/lib/fst240/bpdecode280_74.f90 +++ /dev/null @@ -1,111 +0,0 @@ -subroutine bpdecode280_74(llr,apmask,maxiterations,message74,cw,nharderror,iter,ncheck) -! -! A log-domain belief propagation decoder for the (280,74) code. -! - integer, parameter:: N=280, K=74, M=N-K - integer*1 cw(N),apmask(N) - integer*1 decoded(K) - integer*1 message74(74) - integer nrw(M),ncw - integer Nm(5,M) - integer Mn(3,N) ! 3 checks per bit - integer synd(M) - real tov(3,N) - real toc(5,M) - real tanhtoc(5,M) - real zn(N) - real llr(N) - real Tmn - - include "ldpc_280_74_parity.f90" - - decoded=0 - toc=0 - tov=0 - tanhtoc=0 -! initialize messages to checks - do j=1,M - do i=1,nrw(j) - toc(i,j)=llr((Nm(i,j))) - enddo - enddo - - ncnt=0 - nclast=0 - do iter=0,maxiterations -! Update bit log likelihood ratios (tov=0 in iteration 0). - do i=1,N - if( apmask(i) .ne. 1 ) then - zn(i)=llr(i)+sum(tov(1:ncw,i)) - else - zn(i)=llr(i) - endif - enddo - -! Check to see if we have a codeword (check before we do any iteration). - cw=0 - where( zn .gt. 0. ) cw=1 - ncheck=0 - do i=1,M - synd(i)=sum(cw(Nm(1:nrw(i),i))) - if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 -! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied' - enddo - if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it - decoded=cw(1:74) - call get_crc24(decoded,74,nbadcrc) - nharderror=count( (2*cw-1)*llr .lt. 0.0 ) - if(nbadcrc.eq.0) then - message74=decoded(1:74) - return - endif - endif - - if( iter.gt.0 ) then ! this code block implements an early stopping criterion -! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion - nd=ncheck-nclast - if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased - ncnt=0 ! reset counter - else - ncnt=ncnt+1 - endif -! write(*,*) iter,ncheck,nd,ncnt - if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then - nharderror=-1 - return - endif - endif - nclast=ncheck - -! Send messages from bits to check nodes - do j=1,M - do i=1,nrw(j) - ibj=Nm(i,j) - toc(i,j)=zn(ibj) - do kk=1,ncw ! subtract off what the bit had received from the check - if( Mn(kk,ibj) .eq. j ) then - toc(i,j)=toc(i,j)-tov(kk,ibj) - endif - enddo - enddo - enddo - -! send messages from check nodes to variable nodes - do i=1,M - tanhtoc(1:5,i)=tanh(-toc(1:5,i)/2) - enddo - - do j=1,N - do i=1,ncw - ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j - Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) - call platanh(-Tmn,y) -! y=atanh(-Tmn) - tov(i,j)=2*y - enddo - enddo - - enddo - nharderror=-1 - return -end subroutine bpdecode280_74 diff --git a/lib/fst240/decode280_101.f90 b/lib/fst240/decode280_101.f90 deleted file mode 100644 index 838906c78..000000000 --- a/lib/fst240/decode280_101.f90 +++ /dev/null @@ -1,154 +0,0 @@ -subroutine decode280_101(llr,Keff,maxosd,norder,apmask,message101,cw,ntype,nharderror,dmin) -! -! A hybrid bp/osd decoder for the (280,101) code. -! -! maxosd<0: do bp only -! maxosd=0: do bp and then call osd once with channel llrs -! maxosd>1: do bp and then call osd maxosd times with saved bp outputs -! norder : osd decoding depth -! - integer, parameter:: N=280, K=101, M=N-K - integer*1 cw(N),apmask(N) - integer*1 nxor(N),hdec(N) - integer*1 message101(101),m101(101) - integer nrw(M),ncw - integer Nm(6,M) - integer Mn(3,N) ! 3 checks per bit - integer synd(M) - real tov(3,N) - real toc(6,M) - real tanhtoc(6,M) - real zn(N),zsum(N),zsave(N,3) - real llr(N) - real Tmn - - include "ldpc_280_101_parity.f90" - - maxiterations=30 - nosd=0 - if(maxosd.gt.3) maxosd=3 - if(maxosd.eq.0) then ! osd with channel llrs - nosd=1 - zsave(:,1)=llr - elseif(maxosd.gt.0) then ! - nosd=maxosd - elseif(maxosd.lt.0) then ! just bp - nosd=0 - endif - - toc=0 - tov=0 - tanhtoc=0 -! initialize messages to checks - do j=1,M - do i=1,nrw(j) - toc(i,j)=llr((Nm(i,j))) - enddo - enddo - - ncnt=0 - nclast=0 - zsum=0.0 - do iter=0,maxiterations -! Update bit log likelihood ratios (tov=0 in iteration 0). - do i=1,N - if( apmask(i) .ne. 1 ) then - zn(i)=llr(i)+sum(tov(1:ncw,i)) - else - zn(i)=llr(i) - endif - enddo - zsum=zsum+zn - if(iter.gt.0 .and. iter.le.maxosd) then - zsave(:,iter)=zsum - endif - -! Check to see if we have a codeword (check before we do any iteration). - cw=0 - where( zn .gt. 0. ) cw=1 - ncheck=0 - do i=1,M - synd(i)=sum(cw(Nm(1:nrw(i),i))) - if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 - enddo - if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it - m101=0 - m101(1:101)=cw(1:101) - call get_crc24(m101,101,nbadcrc) - if(nbadcrc.eq.0) then - message101=cw(1:101) - hdec=0 - where(llr .ge. 0) hdec=1 - nxor=ieor(hdec,cw) - nharderror=sum(nxor) - dmin=sum(nxor*abs(llr)) - ntype=1 - return - endif - endif - - if( iter.gt.0 ) then ! this code block implements an early stopping criterion -! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion - nd=ncheck-nclast - if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased - ncnt=0 ! reset counter - else - ncnt=ncnt+1 - endif -! write(*,*) iter,ncheck,nd,ncnt - if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then - nharderror=-1 - exit - endif - endif - nclast=ncheck - -! Send messages from bits to check nodes - do j=1,M - do i=1,nrw(j) - ibj=Nm(i,j) - toc(i,j)=zn(ibj) - do kk=1,ncw ! subtract off what the bit had received from the check - if( Mn(kk,ibj) .eq. j ) then - toc(i,j)=toc(i,j)-tov(kk,ibj) - endif - enddo - enddo - enddo - -! send messages from check nodes to variable nodes - do i=1,M - tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2) - enddo - - do j=1,N - do i=1,ncw - ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j - Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) - call platanh(-Tmn,y) -! y=atanh(-Tmn) - tov(i,j)=2*y - enddo - enddo - - enddo ! bp iterations - - do i=1,nosd - zn=zsave(:,i) - call osd280_101(zn,Keff,apmask,norder,message101,cw,nharderror,dminosd) - if(nharderror.gt.0) then - hdec=0 - where(llr .ge. 0) hdec=1 - nxor=ieor(hdec,cw) - dmin=sum(nxor*abs(llr)) - ntype=2 - return - endif - enddo - - ntype=0 - nharderror=-1 - dminosd=0.0 - - return -end subroutine decode280_101 diff --git a/lib/fst240/decode280_74.f90 b/lib/fst240/decode280_74.f90 deleted file mode 100644 index 0d0c6fc4f..000000000 --- a/lib/fst240/decode280_74.f90 +++ /dev/null @@ -1,153 +0,0 @@ -subroutine decode280_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharderror,dmin) -! -! A hybrid bp/osd decoder for the (280,74) code. -! -! maxosd<0: do bp only -! maxosd=0: do bp and then call osd once with channel llrs -! maxosd>1: do bp and then call osd maxosd times with saved bp outputs -! norder : osd decoding depth -! - integer, parameter:: N=280, K=74, M=N-K - integer*1 cw(N),cwbest(N),apmask(N) - integer*1 nxor(N),hdec(N) - integer*1 message74(74),m74(74) - integer nrw(M),ncw - integer Nm(5,M) - integer Mn(3,N) ! 3 checks per bit - integer synd(M) - real tov(3,N) - real toc(5,M) - real tanhtoc(5,M) - real zn(N),zsum(N),zsave(N,max(1,maxosd)) - real llr(N) - real Tmn - - include "ldpc_280_74_parity.f90" - - maxiterations=30 - nosd=0 - if(maxosd.eq.0) then ! osd with channel llrs - nosd=1 - zsave(:,1)=llr - elseif(maxosd.gt.0) then ! - nosd=maxosd - elseif(maxosd.lt.0) then ! just bp - nosd=0 - endif - - toc=0 - tov=0 - tanhtoc=0 -! initialize messages to checks - do j=1,M - do i=1,nrw(j) - toc(i,j)=llr((Nm(i,j))) - enddo - enddo - - ncnt=0 - nclast=0 - zsum=0.0 - do iter=0,maxiterations -! Update bit log likelihood ratios (tov=0 in iteration 0). - do i=1,N - if( apmask(i) .ne. 1 ) then - zn(i)=llr(i)+sum(tov(1:ncw,i)) - else - zn(i)=llr(i) - endif - enddo - zsum=zsum+zn - if(iter.gt.0 .and. iter.le.maxosd) then - zsave(:,iter)=zsum - endif - -! Check to see if we have a codeword (check before we do any iteration). - cw=0 - where( zn .gt. 0. ) cw=1 - ncheck=0 - do i=1,M - synd(i)=sum(cw(Nm(1:nrw(i),i))) - if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 - enddo - if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it - m74=0 - m74(1:74)=cw(1:74) - call get_crc24(m74,74,nbadcrc) - if(nbadcrc.eq.0) then - message74=cw(1:74) - hdec=0 - where(llr .ge. 0) hdec=1 - nxor=ieor(hdec,cw) - nharderror=sum(nxor) - dmin=sum(nxor*abs(llr)) - ntype=1 - return - endif - endif - - if( iter.gt.0 ) then ! this code block implements an early stopping criterion -! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion - nd=ncheck-nclast - if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased - ncnt=0 ! reset counter - else - ncnt=ncnt+1 - endif -! write(*,*) iter,ncheck,nd,ncnt - if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then - nharderror=-1 - exit - endif - endif - nclast=ncheck - -! Send messages from bits to check nodes - do j=1,M - do i=1,nrw(j) - ibj=Nm(i,j) - toc(i,j)=zn(ibj) - do kk=1,ncw ! subtract off what the bit had received from the check - if( Mn(kk,ibj) .eq. j ) then - toc(i,j)=toc(i,j)-tov(kk,ibj) - endif - enddo - enddo - enddo - -! send messages from check nodes to variable nodes - do i=1,M - tanhtoc(1:5,i)=tanh(-toc(1:5,i)/2) - enddo - - do j=1,N - do i=1,ncw - ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j - Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) - call platanh(-Tmn,y) -! y=atanh(-Tmn) - tov(i,j)=2*y - enddo - enddo - - enddo ! bp iterations - - do i=1,nosd - zn=zsave(:,i) - call osd280_74(zn,Keff,apmask,norder,message74,cw,nharderror,dminosd) - if(nharderror.ge.0) then - hdec=0 - where(llr .ge. 0) hdec=1 - nxor=ieor(hdec,cw) - dmin=sum(nxor*abs(llr)) - ntype=2 - return - endif - enddo - - ntype=0 - nharderror=-1 - dminosd=0.0 - - return -end subroutine decode280_74 diff --git a/lib/fst240/encode280_101.f90 b/lib/fst240/encode280_101.f90 deleted file mode 100644 index e908bb607..000000000 --- a/lib/fst240/encode280_101.f90 +++ /dev/null @@ -1,40 +0,0 @@ -subroutine encode280_101(message,codeword) - integer, parameter:: N=280, K=101, M=N-K - integer*1 codeword(N) - integer*1 gen(M,K) - integer*1 message(K) - integer*1 pchecks(M) - include "ldpc_280_101_generator.f90" - logical first - data first/.true./ - save first,gen - - if( first ) then ! fill the generator matrix - gen=0 - do i=1,M - do j=1,26 - read(g(i)(j:j),"(Z1)") istr - ibmax=4 - if(j.eq.26) ibmax=1 - do jj=1, ibmax - icol=(j-1)*4+jj - if( btest(istr,4-jj) ) gen(i,icol)=1 - enddo - enddo - enddo - first=.false. - endif - - do i=1,M - nsum=0 - do j=1,K - nsum=nsum+message(j)*gen(i,j) - enddo - pchecks(i)=mod(nsum,2) - enddo - - codeword(1:K)=message - codeword(K+1:N)=pchecks - - return -end subroutine encode280_101 diff --git a/lib/fst240/encode280_74.f90 b/lib/fst240/encode280_74.f90 deleted file mode 100644 index a64a57815..000000000 --- a/lib/fst240/encode280_74.f90 +++ /dev/null @@ -1,40 +0,0 @@ -subroutine encode280_74(message,codeword) - integer, parameter:: N=280, K=74, M=N-K - integer*1 codeword(N) - integer*1 gen(M,K) - integer*1 message(K) - integer*1 pchecks(M) - include "ldpc_280_74_generator.f90" - logical first - data first/.true./ - save first,gen - - if( first ) then ! fill the generator matrix - gen=0 - do i=1,M - do j=1,19 - read(g(i)(j:j),"(Z1)") istr - ibmax=4 - if(j.eq.19) ibmax=2 - do jj=1, ibmax - icol=(j-1)*4+jj - if( btest(istr,4-jj) ) gen(i,icol)=1 - enddo - enddo - enddo - first=.false. - endif - - do i=1,M - nsum=0 - do j=1,K - nsum=nsum+message(j)*gen(i,j) - enddo - pchecks(i)=mod(nsum,2) - enddo - - codeword(1:K)=message - codeword(K+1:N)=pchecks - - return -end subroutine encode280_74 diff --git a/lib/fst240/fst280.txt b/lib/fst240/fst280.txt deleted file mode 100644 index 8c9757e40..000000000 --- a/lib/fst240/fst280.txt +++ /dev/null @@ -1,10 +0,0 @@ -------------------------------------------------------------------- - NSPS T/R TxT Tst Txtra Txtra-2.6s DF BW SNR77 SNR50 - (s) (s) (s) (s) (s) (Hz) (Hz) (dB)? (dB)? -------------------------------------------------------------------- - 800 15 10.93 0.5 3.57 0.97 15.00 60.0 -21.3 -22.6 - 1680 30 22.96 1.0 6.04 3.44 7.14 28.6 -24.5 -25.8 - 4000 60 54.67 1.0 4.33 1.73 3.00 12.0 -28.3 -29.6 - 8400 120 114.80 1.0 4.20 1.60 1.43 5.7 -31.5 -32.8 -21504 300 293.89 1.0 5.11 2.51 0.56 2.2 -35.5 -36.8 -------------------------------------------------------------------- diff --git a/lib/fst240/fst280_params.f90 b/lib/fst240/fst280_params.f90 deleted file mode 100644 index dc1519160..000000000 --- a/lib/fst240/fst280_params.f90 +++ /dev/null @@ -1,8 +0,0 @@ -! FT4S280 -! LDPC(280,101)/CRC24 code, six 4x4 Costas arrays for sync, ramp-up and ramp-down symbols - -parameter (KK=77) !Information bits (77 + CRC24) -parameter (ND=140) !Data symbols -parameter (NS=24) !Sync symbols -parameter (NN=NS+ND) !Sync and data symbols (164) -parameter (NN2=NS+ND+2) !Total channel symbols (166) diff --git a/lib/fst240/fst280d.f90 b/lib/fst240/fst280d.f90 deleted file mode 100644 index 45eff351d..000000000 --- a/lib/fst240/fst280d.f90 +++ /dev/null @@ -1,481 +0,0 @@ -program fst280d - -! Decode fst280 data read from *.c2 or *.wav files. - - use packjt77 - include 'fst280_params.f90' - character arg*8,infile*80,fname*16,datetime*11 -! character ch1*1,ch4*4,cseq*31 -! character*22 decodes(100) - character*37 msg - character*120 data_dir - character*77 c77 - character*1 tr_designator - complex, allocatable :: c2(:) - complex, allocatable :: cframe(:) - complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable :: r_data(:) - real*8 fMHz - real llr(280),llra(280),llrb(280),llrc(280),llrd(280) - real candidates(100,3) - real bitmetrics(328,4) - integer hmod,ihdr(11) - integer*2, allocatable :: iwave(:) - integer*1 apmask(280),cw(280) - integer*1 hbits(328) - integer*1 message101(101),message74(74) - logical badsync,unpk77_success - - hmod=1 - Keff=91 - ndeep=3 - iwspr=0 - - nargs=iargc() - if(nargs.lt.1) then - print*,'Usage: fst280d [-a ] [-f fMHz] [-h hmod] [-k Keff] [-d depth] [-t t/r type] file1 [file2 ...]' - go to 999 - endif - iarg=1 - data_dir="." - call getarg(iarg,arg) - if(arg(1:2).eq.'-a') then - call getarg(iarg+1,data_dir) - iarg=iarg+2 - call getarg(iarg,arg) - endif - if(arg(1:2).eq.'-f') then - call getarg(iarg+1,arg) - read(arg,*) fMHz - iarg=iarg+2 - call getarg(iarg,arg) - endif - if(arg(1:2).eq.'-h') then - call getarg(iarg+1,arg) - read(arg,*) hmod - if(hmod.ne.1.and.hmod.ne.2.and.hmod.ne.4.and.hmod.ne.8) then - print*,'invalid modulation index. h must be 1, 2, 4, or 8' - goto 999 - endif - iarg=iarg+2 - call getarg(iarg,arg) - endif - if(arg(1:2).eq.'-k') then - call getarg(iarg+1,arg) - read(arg,*) Keff - if(Keff.le.74) iwspr=1 - iarg=iarg+2 - call getarg(iarg,arg) - endif - if(arg(1:2).eq.'-d') then - call getarg(iarg+1,arg) - read(arg,*) ndeep - iarg=iarg+2 - call getarg(iarg,arg) - endif - if(arg(1:2).eq.'-t') then - call getarg(iarg+1,arg) - read(arg,*) tr_designator - iarg=iarg+2 - endif - - nmax=15*12000 - select case (tr_designator) - case('A') - nsps=800 - nmax=15*12000 - ndown=20/hmod - if(hmod.eq.8) ndown=2 - case('B') - nsps=1680 - nmax=30*12000 - ndown=42/hmod - if(hmod.eq.4) ndown=10 - if(hmod.eq.8) ndown=5 - case('C') - nsps=4000 - nmax=60*12000 - ndown=100/hmod - if(hmod.eq.8) ndown=16 - case('D') - nsps=8400 - nmax=120*12000 - ndown=200/hmod - case('E') - nsps=21504 - nmax=300*12000 - ndown=512/hmod - end select - nss=nsps/ndown - fs=12000.0 !Sample rate - fs2=fs/ndown - nspsec=nint(fs2) - dt=1.0/fs !Sample interval (s) - dt2=1.0/fs2 - tt=nsps*dt !Duration of "itone" symbols (s) - - nfft1=2*int(nmax/2) - nh1=nfft1/2 - allocate( r_data(1:nfft1+2) ) - allocate( c_bigfft(0:nfft1/2) ) - - nfft2=nfft1/ndown - allocate( c2(0:nfft2-1) ) - allocate( cframe(0:164*nss-1) ) - allocate( iwave(nmax) ) - -write(*,*) 'nsps: ',nsps -write(*,*) 'nmax: ',nmax -write(*,*) 'nss : ',nss -write(*,*) 'nspsec: ',fs2 -write(*,*) 'nfft1 : ',nfft1 -write(*,*) 'nfft2 : ',nfft2 - - ngood=0 - ngoodsync=0 - nfile=0 - do ifile=iarg,nargs - nfile=nfile+1 - call getarg(ifile,infile) - open(10,file=infile,status='old',access='stream') - j1=index(infile,'.c2') - j2=index(infile,'.wav') - if(j1.gt.0) then - read(10,end=999) fname,ntrmin,fMHz,c2 - read(fname(8:11),*) nutc - write(datetime,'(i11)') nutc - else if(j2.gt.0) then - read(10,end=999) ihdr,iwave - read(infile(j2-4:j2-1),*) nutc - datetime=infile(j2-11:j2-1) - else - print*,'Wrong file format?' - go to 999 - endif - close(10) - - npts=nmax - fa=100.0 - fb=3500.0 - -! The big fft is done once and is used for calculating the smoothed spectrum -! and also for downconverting/downsampling each candidate. - r_data(1:nfft1)=iwave(1:nfft1) - r_data(nfft1+1:nfft1+2)=0.0 - call four2a(r_data,nfft1,1,-1,0) - c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) - -! Get first approximation of candidate frequencies - call get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candidates) - - ndecodes=0 - isbest1=0 - isbest8=0 - fc21=fc0 - fc28=fc0 - do icand=1,ncand - fc0=candidates(icand,1) - xsnr=candidates(icand,2) - -! Downconvert and downsample a slice of the spectrum centered on the -! rough estimate of the candidates frequency. -! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. -! The size of the downsampled c2 array is nfft2=nfft1/ndown - - call fst280_downsample(c_bigfft,nfft1,ndown,fc0,c2) -! write(*,3001) c2(nfft2/3),candidates(icand,1:2) -!3001 format(2e15.6,2f10.3) - - do isync=0,1 - if(isync.eq.0) then - fc1=0.0 - is0=nint(fs2) - ishw=is0 - isst=4 - ifhw=10 - df=.1*8400/nsps - else if(isync.eq.1) then - fc1=fc28 - is0=isbest8 - ishw=4 - isst=1 - ifhw=10 - df=.02*8400/nsps - endif - - smax1=0.0 - smax8=0.0 - do if=-ifhw,ifhw - fc=fc1+df*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst280(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) - call sync_fst280(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) - if(sync8.gt.smax8) then - fc28=fc - isbest8=istart - smax8=sync8 - endif - if(sync1.gt.smax1) then - fc21=fc - isbest1=istart - smax1=sync1 - endif - enddo - enddo -! write(*,1022) ifile,icand,isync,fc1, & -! fc21,isbest1,smax1,fc28,isbest8,smax8 -!1022 format(i5,1x,i4,1x,i4,1x,f7.2,1x,2(1x,f7.2,1x,i5,1x,e9.3)) - enddo - - if(smax8/smax1 .lt. 0.65 ) then - fc2=fc21 - isbest=isbest1 - ntmax=4 - if(hmod .gt. 1) ntmax=1 - ntmin=1 - njitter=2 - else - fc2=fc28 - isbest=isbest8 - ntmax=4 - if(hmod .gt. 1) ntmax=1 - ntmin=1 - njitter=2 - endif - fc_synced = fc0 + fc2 - dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 - call fst280_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) - - if(abs((isbest-fs2)/nss) .lt. 0.2 .and. abs(fc_synced-1500.0).lt.0.4) then - ngoodsync=ngoodsync+1 - endif - - do ijitter=0,2 - if(ijitter.eq.0) ioffset=0 - if(ijitter.eq.1) ioffset=1 - if(ijitter.eq.2) ioffset=-1 - is0=isbest+ioffset - if(is0.lt.0) cycle - cframe=c2(is0:is0+164*nss-1) - s2=sum(cframe*conjg(cframe)) - cframe=cframe/sqrt(s2) - call get_fst280_bitmetrics(cframe,nss,hmod,bitmetrics,badsync) - - hbits=0 - where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) - ns2=count(hbits( 9: 16).eq.(/0,1,0,0,1,1,1,0/)) - ns3=count(hbits(157:164).eq.(/0,0,0,1,1,0,1,1/)) - ns4=count(hbits(165:172).eq.(/0,1,0,0,1,1,1,0/)) - ns5=count(hbits(313:320).eq.(/0,0,0,1,1,0,1,1/)) - ns6=count(hbits(321:328).eq.(/0,1,0,0,1,1,1,0/)) - nsync_qual=ns1+ns2+ns3+ns4+ns5+ns6 -! if(nsync_qual.lt. 20) cycle - - scalefac=2.83 - llra( 1:140)=bitmetrics( 17:156, 1) - llra(141:280)=bitmetrics(173:312, 1) - llra=scalefac*llra - llrb( 1:140)=bitmetrics( 17:156, 2) - llrb(141:280)=bitmetrics(173:312, 2) - llrb=scalefac*llrb - llrc( 1:140)=bitmetrics( 17:156, 3) - llrc(141:280)=bitmetrics(173:312, 3) - llrc=scalefac*llrc - llrd( 1:140)=bitmetrics( 17:156, 4) - llrd(141:280)=bitmetrics(173:312, 4) - llrd=scalefac*llrd - apmask=0 - - do itry=ntmax,ntmin,-1 - if(itry.eq.1) llr=llra - if(itry.eq.2) llr=llrb - if(itry.eq.3) llr=llrc - if(itry.eq.4) llr=llrd - dmin=0.0 - nharderrors=-1 - unpk77_success=.false. - if(iwspr.eq.0) then - maxosd=2 - call decode280_101(llr,Keff,maxosd,ndeep,apmask,message101,cw,ntype,nharderrors,dmin) - else - maxosd=2 - call decode280_74(llr,Keff,maxosd,ndeep,apmask,message74,cw,ntype,nharderrors,dmin) - endif - if(nharderrors .ge.0) then - if(iwspr.eq.0) then - write(c77,'(77i1)') message101(1:77) - call unpack77(c77,0,msg,unpk77_success) - else - write(c77,'(50i1)') message74(1:50) - c77(51:77)='000000000000000000000110000' - call unpack77(c77,0,msg,unpk77_success) - endif - if(nharderrors .ge.0 .and. unpk77_success) then - ngood=ngood+1 - write(*,1100) nfile,icand,xsnr,dt_synced,fc_synced, & - itry,ntype,nharderrors,dmin,ijitter,nsync_qual,msg(1:22) -1100 format(i5,i5,f6.1,f6.2,f7.1,i4,i4,i4,f7.2,i6,i6,2x,a22) - goto 2002 - else - cycle - endif - endif - enddo ! metrics - enddo ! istart jitter -2002 continue - enddo !candidate list - enddo !files - nfiles=nargs-iarg+1 - write(*,*) 'nfiles: ',nfiles,' ngood: ',ngood,' ngoodsync: ',ngoodsync - write(*,1120) -1120 format("") - -999 end program fst280d - -subroutine sync_fst280(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) - -! Compute sync power for a complex, downsampled FST280 signal. - - include 'fst280_params.f90' - complex cd0(0:np-1) - complex, allocatable, save :: csync(:) - complex, allocatable, save :: csynct(:) - complex ctwk(8*nss) - complex z1,z2,z3 - logical first - integer isyncword(0:7) - integer hmod - real f0save - data isyncword/0,1,3,2,1,0,2,3/ - data first/.true./ - data f0save/0.0/ - save first,twopi,dt,fac,f0save - - p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Statement function for power - - if( first ) then - allocate( csync(8*nss) ) - allocate( csynct(8*nss) ) - twopi=8.0*atan(1.0) - dt=1/fs - k=1 - phi=0.0 - do i=0,7 - dphi=twopi*hmod*(isyncword(i)-1.5)/real(nss) - do j=1,nss - csync(k)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dphi,twopi) - k=k+1 - enddo - enddo - first=.false. - fac=1.0/(8.0*nss) - endif - - if(f0.ne.f0save) then - dphi=twopi*f0*dt - phi=0.0 - do i=1,8*nss - ctwk(i)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dphi,twopi) - enddo - csynct=ctwk*csync - f0save=f0 - endif - - i1=i0 !Costas arrays - i2=i0+78*nss - i3=i0+156*nss - - s1=0.0 - s2=0.0 - s3=0.0 - nsec=8/ncoh - do i=1,nsec - is=(i-1)*ncoh*nss - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - s1=s1+abs(z1)/(8*nss) - s2=s2+abs(z2)/(8*nss) - s3=s3+abs(z3)/(8*nss) - enddo - - sync = s1+s2+s3 - - return -end subroutine sync_fst280 - -subroutine fst280_downsample(c_bigfft,nfft1,ndown,f0,c1) - -! Output: Complex data in c(), sampled at 12000/ndown Hz - - complex c_bigfft(0:nfft1/2) - complex c1(0:nfft1/ndown-1) - - df=12000.0/nfft1 - i0=nint(f0/df) - c1(0)=c_bigfft(i0) - nfft2=nfft1/ndown - do i=1,nfft2/2 - if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) - if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) - enddo - c1=c1/nfft2 - call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain - return - -end subroutine fst280_downsample - -subroutine get_candidates_fst280(c_bigfft,nfft1,nsps,hmod,fs,fa,fb,ncand,candidates) - - complex c_bigfft(0:nfft1/2) - integer hmod - real candidates(100,3) - real s(18000) - real s2(18000) - data nfft1z/-1/ - save nfft1z - - nh1=nfft1/2 - df1=fs/nfft1 - baud=fs/nsps - df2=baud/2.0 - nd=df1/df2 - ndh=nd/2 - ia=fa/df2 - ib=fb/df2 - s=0. - do i=ia,ib - j0=nint(i*df2/df1) - do j=j0-ndh,j0+ndh - s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 - enddo - enddo - call pctile(s(ia:ib),ib-ia+1,30,base) - s=s/base - nh=hmod - do i=ia,ib - s2(i)=s(i-nh*3) + s(i-nh) +s(i+nh) +s(i+nh*3) - s2(i)=db(s2(i)) - 48.5 - enddo - - if(hmod.eq.1) thresh=-29.5 - if(hmod.eq.2) thresh=-27.0 - if(hmod.eq.4) thresh=-27.0 - if(hmod.eq.8) thresh=-27.0 - - ncand=0 - do i=ia,ib - if((s2(i).gt.s2(i-1)).and. & - (s2(i).gt.s2(i+1)).and. & - (s2(i).gt.thresh).and.ncand.lt.100) then - ncand=ncand+1 - candidates(ncand,1)=df2*i - candidates(ncand,2)=s2(i) - endif - enddo - - return -end subroutine get_candidates_fst280 diff --git a/lib/fst240/fst280sim.f90 b/lib/fst240/fst280sim.f90 deleted file mode 100644 index a11bcc7e4..000000000 --- a/lib/fst240/fst280sim.f90 +++ /dev/null @@ -1,143 +0,0 @@ -program fst280sim - -! Generate simulated signals for experimental slow FT4 mode - - use wavhdr - use packjt77 - include 'fst280_params.f90' !Set various constants - type(hdr) h !Header for .wav file - character arg*12,fname*17 - character msg37*37,msgsent37*37,c77*77 - complex, allocatable :: c0(:) - complex, allocatable :: c(:) - real, allocatable :: wave(:) - integer hmod - integer itone(NN) - integer*1 msgbits(101) - integer*2, allocatable :: iwave(:) !Generated full-length waveform - -! Get command-line argument(s) - nargs=iargc() - if(nargs.ne.9) then - print*,'Need 9 arguments, got ',nargs - print*,'Usage: fst280sim "message" TRsec f0 DT h fdop del nfiles snr' - print*,'Examples: fst280sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15' - go to 999 - endif - call getarg(1,msg37) !Message to be transmitted - call getarg(2,arg) - read(arg,*) nsec !TR sequence length, seconds - call getarg(3,arg) - read(arg,*) f00 !Frequency (only used for single-signal) - call getarg(4,arg) - read(arg,*) xdt !Time offset from nominal (s) - call getarg(5,arg) - read(arg,*) hmod !Modulation index, h - call getarg(6,arg) - read(arg,*) fspread !Watterson frequency spread (Hz) - call getarg(7,arg) - read(arg,*) delay !Watterson delay (ms) - call getarg(8,arg) - read(arg,*) nfiles !Number of files - call getarg(9,arg) - read(arg,*) snrdb !SNR_2500 - - nfiles=abs(nfiles) - twopi=8.0*atan(1.0) - fs=12000.0 !Sample rate (Hz) - dt=1.0/fs !Sample interval (s) - nsps=0 - if(nsec.eq.15) nsps=800 - if(nsec.eq.30) nsps=1680 - if(nsec.eq.60) nsps=3888 - if(nsec.eq.120) nsps=8200 - if(nsec.eq.300) nsps=21168 - if(nsps.eq.0) then - print*,'Invalid TR sequence length.' - go to 999 - endif - baud=12000.0/nsps !Keying rate (baud) - nmax=nsec*12000 - nz=nsps*NN - nz2=nsps*NN2 - txt=nz2*dt !Transmission length (s) - tt=nsps*dt !Duration of symbols (s) - allocate( c0(0:nmax-1) ) - allocate( c(0:nmax-1) ) - allocate( wave(nmax) ) - allocate( iwave(nmax) ) - - bandwidth_ratio=2500.0/(fs/2.0) - sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) - if(snrdb.gt.90.0) sig=1.0 - - i3=-1 - n3=-1 - call pack77(msg37,i3,n3,c77) - call genfst280(msg37,0,msgsent37,msgbits,itone,iwspr) - - write(*,*) - write(*,'(a9,a37)') 'Message: ',msgsent37 - write(*,1000) f00,xdt,hmod,txt,snrdb -1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) - write(*,*) - if(i3.eq.1) then - write(*,*) ' mycall hiscall hisgrid' - write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77) - else - write(*,'(a14)') 'Message bits: ' - write(*,'(50i1,1x,24i1)') msgbits - endif - write(*,*) - write(*,'(a17)') 'Channel symbols: ' - write(*,'(10i1)') itone - write(*,*) - -! call sgran() - - fsample=12000.0 - icmplx=1 - f0=f00+1.5*hmod*baud - call gen_fst280wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) - k=nint(xdt/dt) - c0=cshift(c0,-k) - if(k.gt.0) c0(0:k-1)=0.0 - if(k.lt.0) c0(nmax+k:nmax-1)=0.0 - - do ifile=1,nfiles - c=c0 - if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nmax,NZ,fs,delay,fspread) - c=sig*c - wave=real(c) - if(snrdb.lt.90) then - do i=1,nmax !Add gaussian noise at specified SNR - xnoise=gran() - wave(i)=wave(i) + xnoise - enddo - endif - gain=100.0 - if(snrdb.lt.90.0) then - wave=gain*wave - else - datpk=maxval(abs(wave)) - fac=32766.9/datpk - wave=fac*wave - endif - if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." - iwave=nint(wave) - h=default_header(12000,nmax) - if(nmax/12000.le.30) then - write(fname,1102) ifile -1102 format('000000_',i6.6,'.wav') - else - write(fname,1104) ifile -1104 format('000000_',i4.4,'.wav') - endif - open(10,file=trim(fname),status='unknown',access='stream') - write(10) h,iwave !Save to *.wav file - close(10) - write(*,1110) ifile,xdt,f00,snrdb,fname -1110 format(i4,f7.2,f8.2,f7.1,2x,a17) - enddo - -999 end program fst280sim diff --git a/lib/fst240/gen_fst280wave.f90 b/lib/fst240/gen_fst280wave.f90 deleted file mode 100644 index 7a27ca90c..000000000 --- a/lib/fst240/gen_fst280wave.f90 +++ /dev/null @@ -1,98 +0,0 @@ -subroutine gen_fst280wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & - icmplx,cwave,wave) - - parameter(NTAB=65536) - real wave(nwave) - complex cwave(nwave),ctab(0:NTAB-1) - real, allocatable, save :: pulse(:) - real, allocatable :: dphi(:) - integer hmod - integer itone(nsym) -! integer*8 count0,count1,clkfreq - logical first - data first/.true./ - data nsps0/-99/ - save first,twopi,dt,tsym,nsps0,ctab - -! call system_clock(count0,clkfreq) - if(first) then - twopi=8.0*atan(1.0) - do i=0,NTAB-1 - phi=i*twopi/NTAB - ctab(i)=cmplx(cos(phi),sin(phi)) - enddo - endif - - if(first.or.nsps.ne.nsps0) then - if(allocated(pulse)) deallocate(pulse) - allocate(pulse(1:3*nsps)) - dt=1.0/fsample - tsym=nsps/fsample -! Compute the smoothed frequency-deviation pulse - do i=1,3*nsps - tt=(i-1.5*nsps)/real(nsps) - pulse(i)=gfsk_pulse(2.0,tt) - enddo - first=.false. - nsps0=nsps - endif - -! Compute the smoothed frequency waveform. -! Length = (nsym+2)*nsps samples, zero-padded - allocate( dphi(0:(nsym+2)*nsps-1) ) - dphi_peak=twopi*hmod/real(nsps) - dphi=0.0 - do j=1,nsym - ib=(j-1)*nsps - ie=ib+3*nsps-1 - dphi(ib:ie) = dphi(ib:ie) + dphi_peak*pulse(1:3*nsps)*itone(j) - enddo - -! Calculate and insert the audio waveform - phi=0.0 - dphi = dphi + twopi*(f0-1.5*hmod/tsym)*dt !Shift frequency up by f0 - if(icmplx.eq.0) wave=0. - if(icmplx.eq.1) cwave=0. - k=0 - do j=0,(nsym+2)*nsps-1 - k=k+1 - i=phi*float(NTAB)/twopi - i=iand(i,NTAB-1) - if(icmplx.eq.0) then - wave(k)=real(ctab(i)) - else - cwave(k)=ctab(i) - endif - phi=phi+dphi(j) - if(phi.gt.twopi) phi=phi-twopi - enddo - -! Compute the ramp-up and ramp-down symbols - kshift=nsps-nint(fsample) - if(icmplx.eq.0) then - wave(1:nsps/2)=0.0 - wave(nsps/2+1:nsps)=wave(nsps/2+1:nsps) * & - (1.0-cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 - k1=(nsym+1)*nsps+1 - wave(k1+nsps/2:)=0.0 - wave(k1:k1+nsps/2-1)=wave(k1:k1+nsps/2-1) * & - (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 - wave=cshift(wave,kshift) - else - cwave(1:nsps/2)=0.0 - cwave(nsps/2+1:nsps)=cwave(nsps/2+1:nsps) * & - (1.0-cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 - k1=(nsym+1)*nsps+1 - cwave(k1+nsps/2:)=0.0 - cwave(k1:k1+nsps/2-1)=cwave(k1:k1+nsps/2-1) * & - (1.0+cos(twopi*(/(i,i=0,nsps/2-1)/)/real(nsps)))/2.0 - cwave=cshift(cwave,kshift) - endif - -! call system_clock(count1,clkfreq) -! tt=float(count1-count0)/float(clkfreq) -! write(*,3001) tt -!3001 format('Tgen:',f8.3) - - return -end subroutine gen_fst280wave diff --git a/lib/fst240/genfst280.f90 b/lib/fst240/genfst280.f90 deleted file mode 100644 index 919dd2197..000000000 --- a/lib/fst240/genfst280.f90 +++ /dev/null @@ -1,109 +0,0 @@ -subroutine genfst280(msg0,ichk,msgsent,msgbits,i4tone,iwspr) - -! Input: -! - msg0 requested message to be transmitted -! - ichk if ichk=1, return only msgsent -! - msgsent message as it will be decoded -! - i4tone array of audio tone values, {0,1,2,3} -! - iwspr 0: (280,101)/crc24, 1: (280,74)/crc24 -! -! Frame structure: -! s8 d70 s8 d70 s8 - -! Message duration: TxT = 164*8400/12000 = 114.8 s - - use packjt77 - include 'fst280_params.f90' - character*37 msg0 - character*37 message !Message to be generated - character*37 msgsent !Message as it will be received - character*77 c77 - character*24 c24 - integer*4 i4tone(NN),itmp(ND) - integer*1 codeword(2*ND) - integer*1 msgbits(101),rvec(77) - integer isyncword(8) - integer ncrc24 - logical unpk77_success - data isyncword/0,1,3,2,1,0,2,3/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 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/ - message=msg0 - - do i=1, 37 - if(ichar(message(i:i)).eq.0) then - message(i:37)=' ' - exit - endif - enddo - do i=1,37 !Strip leading blanks - if(message(1:1).ne.' ') exit - message=message(i+1:) - enddo - - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent - msgbits=0 - iwspr=0 - if(i3.eq.0.and.n3.eq.6) then - iwspr=1 - read(c77,'(50i1)') msgbits(1:50) - call get_crc24(msgbits,74,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(51:74) - else - read(c77,'(77i1)') msgbits(1:77) - call get_crc24(msgbits,101,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(78:101) - endif - - if(ichk.eq.1) go to 999 - if(unpk77_success) go to 2 -1 msgbits=0 - itone=0 - msgsent='*** bad message *** ' - go to 999 - - entry get_fst280_tones_from_bits(msgbits,i4tone,iwspr) - -2 continue - - if(iwspr.eq.0) then - call encode280_101(msgbits,codeword) - else - call encode280_74(msgbits(1:74),codeword) - endif - -! Grayscale mapping: -! bits tone -! 00 0 -! 01 1 -! 11 2 -! 10 3 - - do i=1,ND - is=codeword(2*i)+2*codeword(2*i-1) - if(is.le.1) itmp(i)=is - if(is.eq.2) itmp(i)=3 - if(is.eq.3) itmp(i)=2 - enddo - - i4tone(1:7)=itmp(1:7) - i4tone(8:14)=itmp(15:21) - i4tone(15:35)=itmp(29:49) - i4tone(36:43)=isyncword - i4tone(44:78)=itmp(50:84) - i4tone(79:86)=isyncword - i4tone(87:121)=itmp(85:119) - i4tone(122:129)=isyncword - i4tone(130:150)=itmp(120:140) - i4tone(151:157)=itmp(22:28) - i4tone(158:164)=itmp(8:14) - -999 return - -end subroutine genfst280 diff --git a/lib/fst240/get_fst280_bitmetrics.f90 b/lib/fst240/get_fst280_bitmetrics.f90 deleted file mode 100644 index 598a385fc..000000000 --- a/lib/fst240/get_fst280_bitmetrics.f90 +++ /dev/null @@ -1,120 +0,0 @@ -subroutine get_fst280_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) - - include 'fst280_params.f90' - complex cd(0:NN*nss-1) - complex cs(0:3,NN) - complex csymb(nss) - complex, allocatable, save :: c1(:,:) ! ideal waveforms, 20 samples per symbol, 4 tones - complex cp(0:3) ! accumulated phase shift over symbol types 0:3 - complex csum,cterm - integer icos8(0:7) - integer graymap(0:3) - integer ip(1) - integer hmod - logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits - logical first - logical badsync - real bitmetrics(2*NN,4) - real s2(0:65535) - real s4(0:3,NN) - data icos8/0,1,3,2,1,0,2,3/ - data graymap/0,1,3,2/ - data first/.true./,nss0/-1/ - save first,one,cp,nss0 - - if(nss.ne.nss0 .and. allocated(c1)) deallocate(c1) - if(first .or. nss.ne.nss0) then - allocate(c1(nss,0:3)) - one=.false. - do i=0,65535 - do j=0,15 - if(iand(i,2**j).ne.0) one(i,j)=.true. - enddo - enddo - twopi=8.0*atan(1.0) - dphi=twopi*hmod/nss - do itone=0,3 - dp=(itone-1.5)*dphi - phi=0.0 - do j=1,nss - c1(j,itone)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dp,twopi) - enddo - cp(itone)=cmplx(cos(phi),sin(phi)) - enddo - first=.false. - endif - - do k=1,NN - i1=(k-1)*NSS - csymb=cd(i1:i1+NSS-1) - do itone=0,3 - cs(itone,k)=sum(csymb*conjg(c1(:,itone))) - enddo - s4(0:3,k)=abs(cs(0:3,k)) - enddo - -! Sync quality check - is1=0 - is2=0 - is3=0 - badsync=.false. - ibmax=0 - - do k=1,8 - ip=maxloc(s4(:,k)) - if(icos8(k-1).eq.(ip(1)-1)) is1=is1+1 - ip=maxloc(s4(:,k+78)) - if(icos8(k-1).eq.(ip(1)-1)) is2=is2+1 - ip=maxloc(s4(:,k+156)) - if(icos8(k-1).eq.(ip(1)-1)) is3=is3+1 - enddo - nsync=is1+is2+is3 !Number of correct hard sync symbols, 0-24 - - badsync=.false. - if(nsync .lt. 8) then - badsync=.true. - return - endif - - bitmetrics=0.0 - do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols - if(nseq.eq.1) nsym=1 - if(nseq.eq.2) nsym=2 - if(nseq.eq.3) nsym=4 - if(nseq.eq.4) nsym=8 - nt=4**nsym - do ks=1,NN-nsym+1,nsym - s2=0 - do i=0,nt-1 - csum=0 - cterm=1 - do j=0,nsym-1 - ntone=mod(i/4**(nsym-1-j),4) - csum=csum+cs(graymap(ntone),ks+j)*cterm - cterm=cterm*conjg(cp(graymap(ntone))) - enddo - s2(i)=abs(csum) - enddo - ipt=1+(ks-1)*2 - if(nsym.eq.1) ibmax=1 - if(nsym.eq.2) ibmax=3 - if(nsym.eq.4) ibmax=7 - if(nsym.eq.8) ibmax=15 - do ib=0,ibmax - bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & - maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) - if(ipt+ib.gt.2*NN) cycle - bitmetrics(ipt+ib,nseq)=bm - enddo - enddo - enddo - bitmetrics(321:328,4)=bitmetrics(321:328,3) - - call normalizebmet(bitmetrics(:,1),2*NN) - call normalizebmet(bitmetrics(:,2),2*NN) - call normalizebmet(bitmetrics(:,3),2*NN) - call normalizebmet(bitmetrics(:,4),2*NN) - return - -end subroutine get_fst280_bitmetrics diff --git a/lib/fst240/ldpc_280_101_generator.f90 b/lib/fst240/ldpc_280_101_generator.f90 deleted file mode 100644 index 521e80026..000000000 --- a/lib/fst240/ldpc_280_101_generator.f90 +++ /dev/null @@ -1,182 +0,0 @@ -character*26 g(179) - -data g/ & - "c919bcbfe4091279702a761e98", & - "51b952dddd36200cf73cc1ed30", & - "15871d32e8e888439180cf6fd8", & - "581f858f6c89ee5ccb91664358", & - "3515e85cedf905eda366a8fc20", & - "e9fcaa6aaa9bab21bc91174e80", & - "0ac73221d424e8747628b13968", & - "4999f7116446f1a7a7a1453a30", & - "0e92773bff2a6d4f09caa48898", & - "7dfaec97c17679f6c3b6a425f0", & - "00707d76a2a7d90297ee39f660", & - "8048cc93fc4ad84ccfc021e6e0", & - "0c13df64062fed419c9bf43400", & - "5523d84459c826b7bc3335d508", & - "828ee2552144d041ed44ada8e0", & - "3f1b89fbd93f674df4813f0898", & - "4e13df64062fed419c9bf43400", & - "5d8645307d3d442991d6efafd0", & - "e5cd9b98d73aab17ce04c4df10", & - "06d26e11e2d02e9cb4f191c2b0", & - "5630cebc5b3a09f7d4fe58fab0", & - "bbfa9591589229738ecbc19288", & - "c98654d1f1f16d507e9bb77cf0", & - "c2af2107bb2bdff49d909dc730", & - "51da7da0c9b1bd18a15f580068", & - "5bdfd83e7ca3097146a5359428", & - "34fc4d397d97ca3ceb272f49a0", & - "6716a6d027ade94010e9aa90b0", & - "62ac7bb089d1a13f6e89f92348", & - "737c3ab63210e195e92e8ad478", & - "db2da5b8a21d22a7122ad80e60", & - "1226525dba4221d4768a495878", & - "a99deb4c9b7d316917b1ece958", & - "8123fb46556f22a0b57bdc7eb0", & - "cc6a80e87a7a9bf8addb17a6a8", & - "3d42bb6ca1c8d30e6cee77aa10", & - "ad15a0c2f36d4409a458cc83c0", & - "766a04039736bd8be23513ae58", & - "257a3da77558d7c707170c30c8", & - "8e54a55fd9f00eb669ab787678", & - "4ef1a73cc9da8670d83bebc588", & - "be8bb82558d44fea1ab27376a0", & - "ea9db4f88c60edf410cb0128d8", & - "a84e19a5261818262ee7247278", & - "51f99e4ea17cf84038d4e00bd0", & - "610560db4095fc44d2465308a0", & - "7688745b59c3d6baa6950c4f50", & - "4b8794914d365b6802bd62a9c8", & - "f62c211d05ed28802b9d278298", & - "b9cd45b2ffa8c0dd688f8d2bc0", & - "68555e81f4227a48e76878bc98", & - "7ab58f11d41a2d38b80d2a7558", & - "aba2d33e69077b6acad393af68", & - "81e5f58fa3ab563e73706201a8", & - "7586aea816750c41671eaa7db8", & - "af37b0a97ba5334a3dd01948e8", & - "4fdc03c263a0c42dcc265f7dc8", & - "b23f2d7f28748944cdfffd5af0", & - "5c1e6f37dfba8feacaafdb0f78", & - "3a85b051f4f1c930d921f60828", & - "72319352bd8022ce2cae2e7858", & - "78b79f633ac6879e3ac3a005a0", & - "9f0c470609669953b23328de60", & - "86d3745d50142c82a066ab9490", & - "743e7bf411490f36a9799e37e8", & - "9b8378677870933ef360d7e418", & - "5f7adbf515b663a1434b0d47d8", & - "13249a96b14c6cdcfae5009eb0", & - "da9570e0a52125d0dc4dec4430", & - "ada13ce2dbcb57e2f5b31172f0", & - "84f5485886d4157e9d37efb4d0", & - "23f58c3200bab4ae5dee54edd0", & - "d4377aadf8acb19d4369613ac8", & - "17cefcf65c87885fb6c4d537a0", & - "59d70b8536488298930aaea7f8", & - "49e8dbb08c2ecdaa84bb6a5378", & - "e1694479ecc1f87e503f959e50", & - "dbb3fc94f0f70d4bd4dcf302d8", & - "4ccb3a56f80c236424683b1588", & - "f4f123c72596a00397d56fcdf8", & - "13f9cf266a6957b87cd2b576f0", & - "0904d341bc0878460cd8361ac0", & - "69fd534caf2cccf9c90659a038", & - "757d3d95089a5bc20a7b77c618", & - "30df1d7b8124415c73190b08d8", & - "d39319584987dce0c44176d5d8", & - "1a81df299eb7434a5b6b9322a0", & - "fe4acfab1c22c7bea222f1a6b0", & - "2f2fde37fa8f87a318f7bcda10", & - "fae712210c23665aa7a3f10620", & - "977b8407c7fd22d7715077ee78", & - "2ab2b355b3477df0b738c49d48", & - "93a2468cfd11a522b310069d88", & - "0e5ae6e789ded3c0d436359318", & - "9ece0b13a3c06d560a15d3c448", & - "838e8bbf5e671503ea72ba3118", & - "7c827de9a87d740763c69c6778", & - "1fe395e4e2e6d1373602243488", & - "f2c4efee3d0ce2e22749be9e20", & - "46405cca0e40f36ab83de4a998", & - "8b6e931355a79630ef2dbdbdb8", & - "10df1d3b8124415c72190b08d8", & - "cdff258b07a4f7cfe5c2210ba8", & - "1515e85cedf904eda366a8fc20", & - "a38276f2d077abc1da5e177868", & - "67a7b5ab66f21f391d306c3330", & - "29492cc630f9bad1fdedf0c990", & - "490a6dd38170eab178f7cebf78", & - "ca9db4e88c60edf410cf0128d8", & - "e3f1c23fa8531fb1e4c7768d88", & - "39d7d8fbbb689b2a9bedfd4dd0", & - "d1b952dd5d36200cf734c1ed30", & - "0820a5ccb970d1ab109d84d700", & - "58bc3c509fcd7874e9b1533ba8", & - "08ed7724ac66b7974499b12f40", & - "4738529b2fd04afd89184b64b8", & - "7155b496e3b9f687135b4c55b8", & - "b5d1d3cf38b1765dd730d8b960", & - "296de2c373773a869b9cf804c8", & - "1cdf18b99bcc47ae72bf59df68", & - "ad0888db89dd794be0b2660e98", & - "1f2a8db9db19cd4d69a735d930", & - "44b720007480382206fdbfbb18", & - "c63817aad3801fb993ea9032c0", & - "d44707db5a0b489fd48748cca8", & - "49f98a67c6e128a5300f7ccc50", & - "04849fa9da91d4514355406388", & - "dfad3a11788cf6f6517f987de8", & - "47078a19e38a0763cabd7c8d70", & - "aafa7f864f0da5bc78f8e57ba8", & - "8acb5a34e18e111023b3e7b1f8", & - "5acc41263d6aa1767e5e6acdc8", & - "27623a9f6c1174e35394191820", & - "1f2bde9c006b3b687964b1c5e0", & - "b01c6e357bce202244b4a88d08", & - "61c85d74d7e97576507c9b0e88", & - "bcad5a44d75ae40bc43559d268", & - "10584eaf319552194418563de0", & - "b29b011d717d10a22de0983980", & - "2f9b42d7d2299449491c612b20", & - "389ba33f5fec3bfb3a0ef86b50", & - "3df89f78c19fb27ae7ff19d360", & - "65ff6ba4e107aa919a6afb4ff0", & - "39b607c3f09679a62e134cd390", & - "94ad06f7b7414727d92f998930", & - "169200459898ae0bc7f06714a0", & - "c7a5a945adebb554cb4d86a830", & - "f37c3ab63230e195e92e8ad478", & - "559a51262e91aa9ba0fa96af48", & - "fb2998ca916a557463d00fb160", & - "aa32462ada57a76ae132fc8de8", & - "e6df6b19f58bfee0b96b731b90", & - "e984335d40a54fe914a6249110", & - "ea73d8f3f14bd9fe2374e39120", & - "3adab8e51c36f53584e3669c88", & - "74ef69f64dc4fef86c3b1fe640", & - "d01c6bc112d7ae3e4ba4820a78", & - "62923979fd3c3d1153bcaaf338", & - "038f72995b5072df8fe5f4dfa0", & - "9f07e7cea2f1476fb035978790", & - "2a5aad6a75d5c86cab38fd0070", & - "a254a09cc3180854688d2aa9c8", & - "0495639712a04820f7038ae7c0", & - "d99fc716ca825ad45cca8f4518", & - "01b8d558073c0377ce67344a50", & - "2fbd0f86a17c3f93713fbd09a0", & - "c29dc84bec7b4cd00dd1c17380", & - "5e6238b823f530ae017a03f0e0", & - "51203d329c68b061977d78d4c0", & - "1186729e08cf1dfbec30237968", & - "40363018b431224a1f559d2908", & - "e334e78442b614a0c9a377e1b8", & - "ff2eda86339f589f96382f52e0", & - "58a30e07fc7a37a4f858623778", & - "f5067fe407a4c3b94ce7b63e48", & - "1d09ced788a3642bc0ec640ec8", & - "17734ca67d53cd9d8595970668", & - "47953c2105bd94bff079672740", & - "3444682d1dc0ab486036c1b0d0"/ diff --git a/lib/fst240/ldpc_280_101_parity.f90 b/lib/fst240/ldpc_280_101_parity.f90 deleted file mode 100644 index b1cabb7d1..000000000 --- a/lib/fst240/ldpc_280_101_parity.f90 +++ /dev/null @@ -1,476 +0,0 @@ -data Mn/ & - 150, 151, 161, & - 6, 164, 172, & - 92, 128, 158, & - 2, 63, 135, & - 3, 14, 22, & - 4, 18, 29, & - 5, 17, 164, & - 7, 99, 179, & - 8, 88, 115, & - 9, 62, 110, & - 10, 107, 154, & - 11, 50, 140, & - 12, 28, 33, & - 13, 31, 170, & - 15, 69, 175, & - 16, 77, 178, & - 19, 70, 91, & - 20, 95, 177, & - 21, 96, 106, & - 23, 129, 168, & - 24, 49, 169, & - 25, 65, 102, & - 26, 82, 171, & - 27, 45, 137, & - 30, 89, 119, & - 32, 148, 158, & - 34, 94, 152, & - 35, 44, 92, & - 36, 39, 138, & - 37, 55, 58, & - 38, 121, 165, & - 40, 81, 162, & - 41, 139, 150, & - 42, 43, 83, & - 46, 80, 114, & - 47, 52, 54, & - 48, 166, 173, & - 38, 53, 87, & - 56, 64, 126, & - 57, 67, 127, & - 59, 156, 159, & - 60, 97, 133, & - 61, 118, 161, & - 66, 100, 123, & - 68, 124, 131, & - 71, 101, 155, & - 72, 74, 144, & - 73, 112, 141, & - 75, 136, 149, & - 59, 78, 117, & - 79, 130, 163, & - 84, 93, 113, & - 86, 108, 163, & - 103, 146, 157, & - 70, 104, 145, & - 105, 128, 142, & - 74, 109, 122, & - 54, 111, 153, & - 116, 154, 176, & - 120, 132, 167, & - 21, 125, 147, & - 134, 143, 166, & - 7, 81, 160, & - 32, 99, 174, & - 1, 93, 104, & - 2, 69, 98, & - 3, 33, 152, & - 4, 46, 159, & - 5, 126, 178, & - 6, 127, 147, & - 8, 101, 110, & - 9, 73, 158, & - 10, 120, 123, & - 11, 122, 125, & - 12, 58, 170, & - 13, 88, 105, & - 14, 133, 150, & - 15, 92, 100, & - 16, 90, 108, & - 17, 44, 106, & - 18, 35, 175, & - 19, 94, 179, & - 20, 97, 153, & - 22, 109, 130, & - 23, 63, 140, & - 24, 37, 146, & - 25, 141, 168, & - 26, 95, 115, & - 27, 107, 149, & - 28, 91, 168, & - 29, 134, 144, & - 30, 31, 169, & - 34, 40, 96, & - 36, 156, 172, & - 39, 61, 135, & - 41, 42, 121, & - 43, 57, 117, & - 45, 62, 72, & - 47, 137, 167, & - 48, 83, 116, & - 49, 65, 173, & - 1, 50, 141, & - 2, 8, 150, & - 3, 62, 140, & - 4, 104, 124, & - 5, 128, 139, & - 6, 64, 159, & - 7, 103, 176, & - 2, 11, 104, & - 9, 71, 85, & - 10, 80, 131, & - 11, 17, 130, & - 12, 148, 156, & - 13, 39, 164, & - 14, 15, 167, & - 14, 32, 89, & - 16, 114, 135, & - 8, 164, 169, & - 18, 107, 129, & - 19, 53, 102, & - 20, 134, 170, & - 21, 43, 145, & - 22, 24, 76, & - 23, 44, 146, & - 19, 22, 101, & - 25, 41, 48, & - 26, 46, 58, & - 27, 82, 87, & - 28, 78, 179, & - 29, 73, 81, & - 30, 116, 161, & - 31, 96, 157, & - 15, 58, 172, & - 10, 33, 160, & - 34, 110, 118, & - 33, 35, 113, & - 36, 166, 175, & - 32, 37, 152, & - 38, 57, 74, & - 13, 82, 176, & - 40, 42, 45, & - 25, 57, 177, & - 40, 120, 136, & - 21, 92, 121, & - 23, 34, 147, & - 12, 45, 54, & - 3, 46, 48, & - 47, 91, 169, & - 26, 61, 132, & - 49, 123, 147, & - 1, 79, 88, & - 51, 97, 101, & - 52, 155, 177, & - 24, 72, 105, & - 54, 84, 106, & - 55, 63, 126, & - 56, 72, 163, & - 38, 63, 170, & - 37, 71, 178, & - 20, 49, 59, & - 30, 60, 117, & - 61, 65, 137, & - 41, 98, 119, & - 47, 51, 62, & - 6, 76, 131, & - 55, 70, 81, & - 66, 111, 119, & - 60, 67, 94, & - 68, 112, 132, & - 9, 69, 157, & - 70, 75, 89, & - 69, 108, 153, & - 44, 53, 77, & - 29, 130, 149, & - 65, 103, 125, & - 74, 85, 156, & - 56, 67, 68, & - 77, 138, 144, & - 28, 95, 138, & - 79, 133, 142, & - 35, 50, 86, & - 73, 78, 137, & - 27, 126, 175, & - 83, 100, 143, & - 42, 142, 168, & - 40, 48, 158, & - 86, 95, 174, & - 39, 109, 129, & - 59, 88, 125, & - 6, 89, 155, & - 36, 90, 102, & - 75, 97, 141, & - 43, 146, 148, & - 93, 149, 168, & - 52, 83, 94, & - 80, 87, 106, & - 91, 96, 143, & - 3, 43, 126, & - 98, 154, 162, & - 99, 115, 173, & - 5, 84, 100, & - 64, 133, 154, & - 90, 117, 158, & - 7, 108, 151, & - 4, 128, 167, & - 105, 127, 136, & - 1, 83, 114, & - 107, 127, 134, & - 4, 108, 170, & - 92, 109, 171, & - 110, 113, 122, & - 111, 124, 166, & - 12, 112, 150, & - 2, 95, 105, & - 17, 114, 118, & - 99, 139, 144, & - 116, 165, 178, & - 5, 22, 73, & - 16, 115, 162, & - 13, 34, 41, & - 120, 122, 151, & - 121, 160, 172, & - 8, 37, 102, & - 123, 140, 165, & - 7, 53, 93, & - 9, 10, 130, & - 11, 30, 58, & - 31, 66, 179, & - 14, 31, 45, & - 15, 88, 129, & - 18, 101, 148, & - 16, 62, 127, & - 17, 20, 68, & - 19, 86, 98, & - 25, 106, 163, & - 135, 152, 163, & - 23, 124, 137, & - 21, 28, 71, & - 24, 26, 153, & - 29, 90, 123, & - 32, 113, 134, & - 35, 57, 169, & - 27, 50, 139, & - 33, 60, 65, & - 38, 61, 142, & - 145, 153, 154, & - 39, 67, 81, & - 36, 84, 133, & - 18, 161, 173, & - 93, 155, 171, & - 42, 99, 131, & - 49, 87, 162, & - 51, 56, 168, & - 47, 125, 144, & - 44, 143, 159, & - 46, 75, 138, & - 52, 78, 107, & - 54, 109, 174, & - 64, 110, 179, & - 159, 165, 174, & - 66, 135, 171, & - 63, 76, 117, & - 59, 111, 120, & - 72, 160, 166, & - 70, 118, 156, & - 55, 157, 173, & - 74, 100, 176, & - 77, 112, 145, & - 69, 141, 147, & - 94, 140, 151, & - 51, 82, 104, & - 85, 98, 167, & - 80, 119, 146, & - 97, 122, 172, & - 90, 96, 132, & - 79, 91, 178, & - 103, 136, 152, & - 1, 76, 85, & - 115, 121, 149, & - 116, 175, 177/ - -data Nm/ & - 65, 102, 151, 207, 278, 0, & - 4, 66, 103, 109, 214, 0, & - 5, 67, 104, 147, 198, 0, & - 6, 68, 105, 205, 209, 0, & - 7, 69, 106, 201, 218, 0, & - 2, 70, 107, 165, 190, 0, & - 8, 63, 108, 204, 225, 0, & - 9, 71, 103, 118, 223, 0, & - 10, 72, 110, 170, 226, 0, & - 11, 73, 111, 134, 226, 0, & - 12, 74, 109, 112, 227, 0, & - 13, 75, 113, 146, 213, 0, & - 14, 76, 114, 140, 220, 0, & - 5, 77, 115, 116, 229, 0, & - 15, 78, 115, 133, 230, 0, & - 16, 79, 117, 219, 232, 0, & - 7, 80, 112, 215, 233, 0, & - 6, 81, 119, 231, 249, 0, & - 17, 82, 120, 125, 234, 0, & - 18, 83, 121, 160, 233, 0, & - 19, 61, 122, 144, 238, 0, & - 5, 84, 123, 125, 218, 0, & - 20, 85, 124, 145, 237, 0, & - 21, 86, 123, 154, 239, 0, & - 22, 87, 126, 142, 235, 0, & - 23, 88, 127, 149, 239, 0, & - 24, 89, 128, 183, 243, 0, & - 13, 90, 129, 179, 238, 0, & - 6, 91, 130, 174, 240, 0, & - 25, 92, 131, 161, 227, 0, & - 14, 92, 132, 228, 229, 0, & - 26, 64, 116, 138, 241, 0, & - 13, 67, 134, 136, 244, 0, & - 27, 93, 135, 145, 220, 0, & - 28, 81, 136, 181, 242, 0, & - 29, 94, 137, 191, 248, 0, & - 30, 86, 138, 159, 223, 0, & - 31, 38, 139, 158, 245, 0, & - 29, 95, 114, 188, 247, 0, & - 32, 93, 141, 143, 186, 0, & - 33, 96, 126, 163, 220, 0, & - 34, 96, 141, 185, 251, 0, & - 34, 97, 122, 193, 198, 0, & - 28, 80, 124, 173, 255, 0, & - 24, 98, 141, 146, 229, 0, & - 35, 68, 127, 147, 256, 0, & - 36, 99, 148, 164, 254, 0, & - 37, 100, 126, 147, 186, 0, & - 21, 101, 150, 160, 252, 0, & - 12, 102, 181, 243, 0, 0, & - 152, 164, 253, 271, 0, 0, & - 36, 153, 195, 257, 0, 0, & - 38, 120, 173, 225, 0, 0, & - 36, 58, 146, 155, 258, 0, & - 30, 156, 166, 266, 0, 0, & - 39, 157, 177, 253, 0, 0, & - 40, 97, 139, 142, 242, 0, & - 30, 75, 127, 133, 227, 0, & - 41, 50, 160, 189, 263, 0, & - 42, 161, 168, 244, 0, 0, & - 43, 95, 149, 162, 245, 0, & - 10, 98, 104, 164, 232, 0, & - 4, 85, 156, 158, 262, 0, & - 39, 107, 202, 259, 0, 0, & - 22, 101, 162, 175, 244, 0, & - 44, 167, 228, 261, 0, 0, & - 40, 168, 177, 247, 0, 0, & - 45, 169, 177, 233, 0, 0, & - 15, 66, 170, 172, 269, 0, & - 17, 55, 166, 171, 265, 0, & - 46, 110, 159, 238, 0, 0, & - 47, 98, 154, 157, 264, 0, & - 48, 72, 130, 182, 218, 0, & - 47, 57, 139, 176, 267, 0, & - 49, 171, 192, 256, 0, 0, & - 123, 165, 262, 278, 0, 0, & - 16, 173, 178, 268, 0, 0, & - 50, 129, 182, 257, 0, 0, & - 51, 151, 180, 276, 0, 0, & - 35, 111, 196, 273, 0, 0, & - 32, 63, 130, 166, 247, 0, & - 23, 128, 140, 271, 0, 0, & - 34, 100, 184, 195, 207, 0, & - 52, 155, 201, 248, 0, 0, & - 110, 176, 272, 278, 0, 0, & - 53, 181, 187, 234, 0, 0, & - 38, 128, 196, 252, 0, 0, & - 9, 76, 151, 189, 230, 0, & - 25, 116, 171, 190, 0, 0, & - 79, 191, 203, 240, 275, 0, & - 17, 90, 148, 197, 276, 0, & - 3, 28, 78, 144, 210, 0, & - 52, 65, 194, 225, 250, 0, & - 27, 82, 168, 195, 270, 0, & - 18, 88, 179, 187, 214, 0, & - 19, 93, 132, 197, 275, 0, & - 42, 83, 152, 192, 274, 0, & - 66, 163, 199, 234, 272, 0, & - 8, 64, 200, 216, 251, 0, & - 44, 78, 184, 201, 267, 0, & - 46, 71, 125, 152, 231, 0, & - 22, 120, 191, 223, 0, 0, & - 54, 108, 175, 277, 0, 0, & - 55, 65, 105, 109, 271, 0, & - 56, 76, 154, 206, 214, 0, & - 19, 80, 155, 196, 235, 0, & - 11, 89, 119, 208, 257, 0, & - 53, 79, 172, 204, 209, 0, & - 57, 84, 188, 210, 258, 0, & - 10, 71, 135, 211, 259, 0, & - 58, 167, 212, 263, 0, 0, & - 48, 169, 213, 268, 0, 0, & - 52, 136, 211, 241, 0, 0, & - 35, 117, 207, 215, 0, 0, & - 9, 88, 200, 219, 279, 0, & - 59, 100, 131, 217, 280, 0, & - 50, 97, 161, 203, 262, 0, & - 43, 135, 215, 265, 0, 0, & - 25, 163, 167, 273, 0, 0, & - 60, 73, 143, 221, 263, 0, & - 31, 96, 144, 222, 279, 0, & - 57, 74, 211, 221, 274, 0, & - 44, 73, 150, 224, 240, 0, & - 45, 105, 212, 237, 0, 0, & - 61, 74, 175, 189, 254, 0, & - 39, 69, 156, 183, 198, 0, & - 40, 70, 206, 208, 232, 0, & - 3, 56, 106, 205, 0, 0, & - 20, 119, 188, 230, 0, 0, & - 51, 84, 112, 174, 226, 0, & - 45, 111, 165, 251, 0, 0, & - 60, 149, 169, 275, 0, 0, & - 42, 77, 180, 202, 248, 0, & - 62, 91, 121, 208, 241, 0, & - 4, 95, 117, 236, 261, 0, & - 49, 143, 206, 277, 0, 0, & - 24, 99, 162, 182, 237, 0, & - 29, 178, 179, 256, 0, 0, & - 33, 106, 216, 243, 0, 0, & - 12, 85, 104, 224, 270, 0, & - 48, 87, 102, 192, 269, 0, & - 56, 180, 185, 245, 0, 0, & - 62, 184, 197, 255, 0, 0, & - 47, 91, 178, 216, 254, 0, & - 55, 122, 246, 268, 0, 0, & - 54, 86, 124, 193, 273, 0, & - 61, 70, 145, 150, 269, 0, & - 26, 113, 193, 231, 0, 0, & - 49, 89, 174, 194, 279, 0, & - 1, 33, 77, 103, 213, 0, & - 1, 204, 221, 270, 0, 0, & - 27, 67, 138, 236, 277, 0, & - 58, 83, 172, 239, 246, 0, & - 11, 59, 199, 202, 246, 0, & - 46, 153, 190, 250, 0, 0, & - 41, 94, 113, 176, 265, 0, & - 54, 132, 170, 266, 0, 0, & - 3, 26, 72, 186, 203, 0, & - 41, 68, 107, 255, 260, 0, & - 63, 134, 222, 264, 0, 0, & - 1, 43, 131, 249, 0, 0, & - 32, 199, 219, 252, 0, 0, & - 51, 53, 157, 235, 236, 0, & - 2, 7, 114, 118, 0, 0, & - 31, 217, 224, 260, 0, 0, & - 37, 62, 137, 212, 264, 0, & - 60, 99, 115, 205, 272, 0, & - 20, 87, 90, 185, 194, 253, & - 21, 92, 118, 148, 242, 0, & - 14, 75, 121, 158, 209, 0, & - 23, 210, 250, 261, 0, 0, & - 2, 94, 133, 222, 274, 0, & - 37, 101, 200, 249, 266, 0, & - 64, 187, 258, 260, 0, 0, & - 15, 81, 137, 183, 280, 0, & - 59, 108, 140, 267, 0, 0, & - 18, 142, 153, 280, 0, 0, & - 16, 69, 159, 217, 276, 0, & - 8, 82, 129, 228, 259, 0/ - -data nrw/ & -5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, & -5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, & -5,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,5,5,5,4, & -5,5,5,4,5,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4, & -5,4,5,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5, & -5,4,4,5,5,5,5,5,5,5,4,4,4,4,5,5,5,4,4,5, & -5,5,5,4,5,5,5,4,4,5,4,4,5,5,5,4,5,4,4,5, & -5,4,4,5,4,5,5,4,5,5,4,5,5,5,4,5,4,5,5,4, & -4,4,5,4,4,5,5,6,5,5,4,5,5,4,5,4,4,5,5/ - -ncw=3 - diff --git a/lib/fst240/ldpc_280_74_generator.f90 b/lib/fst240/ldpc_280_74_generator.f90 deleted file mode 100644 index 8625e2fd2..000000000 --- a/lib/fst240/ldpc_280_74_generator.f90 +++ /dev/null @@ -1,209 +0,0 @@ -character*19 g(206) - -data g/ & - "f7842fd3230388e2388", & - "2ebea0b08a75d2261cc", & - "b037d38c9d9b9a5e520", & - "936729d89fd5474ecdc", & - "539287b4ef7ee4534a8", & - "a4d283607d3a5020508", & - "f4539f434b8b8585444", & - "1c7b56480cc52fa5228", & - "a1c788b066ac91de648", & - "6592203e5579bbd9248", & - "aaa9e1247a75c451654", & - "f06cbce3477735fcdac", & - "0b3bd1b2eb21c4a58e8", & - "9789c1e9afeaefe132c", & - "6f3090a344262fe9588", & - "523326e51ec096314c0", & - "33ad630efa2f0547a1c", & - "128e4669c5290997554", & - "d21ba68abe8a45c7388", & - "14792ff07616833ddcc", & - "f336703cec81b57b9d4", & - "dcb179c1ede8a193578", & - "19a5027744d4d5fc3ec", & - "416cb1bc4f9fc83f03c", & - "245f12d8a19902ff678", & - "3a9653df6b08f65e934", & - "94870f042c4015d30d0", & - "7db806a2e50336e78bc", & - "d799458b3559526d2a8", & - "77e7cfd440146912610", & - "67c9ca176f188a99b1c", & - "dd736cb5cbfaa6f6cb0", & - "1210f8c1310dde522e4", & - "3bdf62af1d111a616a8", & - "556e0b2cb64629c03e0", & - "153b771b34fd0e24038", & - "677111e1bd26700abec", & - "ba6a2362c2249224dc8", & - "96d96eda9f7d897b3a4", & - "ee632974db8208ed678", & - "ba6e8ace7ca7e5dba2c", & - "112aa2048b8723c3794", & - "04125e68eed114d3a74", & - "6ce3283112a3d15df18", & - "6717fa02c4245ac3cd4", & - "bba51cf56c4ab60d0e8", & - "bf02614f56d95557004", & - "db8d9537a66dae71170", & - "2aa9e1247a75c451614", & - "37887845236cdc5a498", & - "5a0fd4682a5116e3bd4", & - "66a13f0f4838812f4b0", & - "0189837a15fb8a3ea28", & - "bd833c6eb639530bb4c", & - "ad2cb697dcd08717134", & - "d28c4e5b0e4f93921e8", & - "4a10da97be29877762c", & - "11b1d2dbd7e029e0034", & - "8cebf77857fd5b4b2d0", & - "8cf76e6929f04a6f2d0", & - "4dfdef39d983b6ff054", & - "e19594dcc430c3f36f8", & - "b4e0a5979e86ca9e7d8", & - "c6e5822a81c720e1da8", & - "d8b1374afa4f4534c2c", & - "d50ebca7ce5022d72b8", & - "d1af50dba58c8b978d4", & - "0114771daca21b8a4e8", & - "5a12be303c2bcc6cad0", & - "75ba0d26c70194e20dc", & - "feeb4567ccdd6d44334", & - "de993868f8b317cdb08", & - "8c0f2fc7b031a0354ec", & - "df2ddab6d334a1316fc", & - "d410f54de1453f63024", & - "14870f042c4011d30d0", & - "bf8bb7654c089ff49f4", & - "48fe5211864e84af104", & - "a212348c05d3f2f7c8c", & - "1cb6e7158001aa32fa0", & - "bb2700d89c358ea9f74", & - "f5ff926daf5e6003708", & - "7eecbcdc28e9800b97c", & - "b38c9a3ff4e36761180", & - "aff8af260682347a39c", & - "24c2e6bf10c093cb8b8", & - "7633edd7825917114ec", & - "3383b1074eee8343950", & - "3d0636cf743b45409bc", & - "e6191c1e4753a438054", & - "a5ed8c6a5c54aaa2d0c", & - "2335c47d4da16e79fd4", & - "56f62a484a6243fea04", & - "090c7572a6b53ed67d8", & - "a12212511d2fe5a7a04", & - "55653c6f1cd716dfafc", & - "25fb9166056f5276e50", & - "b5500cd4a5a4903b794", & - "5aaa65c6ee1732ffa20", & - "702a7660612fd7307fc", & - "bbf00390ef7bb4219f4", & - "36a23bd84e7d142dc28", & - "00dd156a637e5b6cf34", & - "d960448d1d09f7a3d5c", & - "7cc7c47ef82e670f740", & - "0c72af8643fa31e0df8", & - "c60997484551c3304ec", & - "5234c7b54ce0fb97cd4", & - "e4551cf6ddc5bf7b85c", & - "7320bbe8f600cb3f654", & - "b25ac980a31e7d449e8", & - "da25337deba0f2a1024", & - "4b54fafbcdf9f159c70", & - "75252e36d57dc65a0c8", & - "9f792800ecd943f8784", & - "fb7d1b209de7997cd40", & - "f47e660b960bf39cda4", & - "630017e41ef1e01b3bc", & - "047d83c03cd1e69929c", & - "0b8be375675a21f6c50", & - "aebfa0b08a75d2261cc", & - "dcd8bfe5b2b83f3276c", & - "862503814b89c46f268", & - "caf108899bef63422e0", & - "0651e9975e9eb3049bc", & - "d2418a98d6be4bb1368", & - "0f886c109cbf0643a64", & - "ae76a8d1d71335942cc", & - "66a0d75d3f90f0d0c04", & - "51d30039a555c4ac8cc", & - "9d7a4b82e9323439734", & - "2475d34a372b289eba4", & - "2468b9122171f215a80", & - "f1eb642be43a6d15e74", & - "001d6a58165ada8f124", & - "dd770baa38e1f8c2fd8", & - "03e026dcb395529dc0c", & - "46dc96eb5146f71a614", & - "1402ba94f9d9e1ff3dc", & - "dd7970ccb883bf18678", & - "29ddaca7cd0bf0151f4", & - "865c5ec3ab28496ade4", & - "97d388a7557a659e7f8", & - "78ba47aec4ff81965dc", & - "26a0c75d3f90f0d0c04", & - "48bc3be9b33ad3a2960", & - "e9c4c425a39b4fa6520", & - "2a8cfed864a4c6f5bb8", & - "de273ccb39330dd42a0", & - "c7e0c4a6641be9a6934", & - "f8b8514aebccc0086a4", & - "0f2b8fda05f0d07629c", & - "8734be755b106490e04", & - "789a87c164b552602d4", & - "b588408fb1a6c128874", & - "9dddcc7da27769ac544", & - "288b20a6f933bab6328", & - "f38c9a3ff4e26761180", & - "dc5613392113fea3498", & - "62dcbccf74e9673662c", & - "729e135a6b13b1eb084", & - "3045e9bb3c808018868", & - "0d1e2b1a48642a04dac", & - "abb1dced614797b1288", & - "d29fba8d71829beb4a0", & - "8f4a38515de6db613c4", & - "67194fd309de34d2178", & - "fc73d1f5ea8fd6bf49c", & - "c6289740e2b97b8d29c", & - "6100d464faa8f4f3068", & - "2cb7e414a3da6ca0988", & - "b439b0fdfdf891f28ec", & - "b7d3aaa693c7f068120", & - "25d691a2bc6288c1c50", & - "52f1f88c882d24a5f9c", & - "9892d88821ebd874f1c", & - "fbda9cdf96a2c4e9b30", & - "7716ec58ca1ac237f90", & - "6993c923557c6c68b68", & - "eb32c8c6a30622d0c28", & - "ba7980eafa803e1d3dc", & - "a92b5a9ca961bf9a5bc", & - "36ecfc5928f2c7be4cc", & - "ab854e4b7a9944840d4", & - "62db1428386b97101e4", & - "734bc6eb48e3024c7a0", & - "5b06c92d9089c7e6e38", & - "c7d02e44052506c6d14", & - "d35f553090ce90d3b04", & - "5462cf72405e2525d7c", & - "c9b85ab24e5188e5d18", & - "d0bb27c6092eb01dc7c", & - "37036df9c68bfe4eb24", & - "4387156e9b00d277ce0", & - "a39bb776102878c96a4", & - "d6f1cd9b329e7d0b374", & - "d74ba376dbaa9de5270", & - "58df754b03e0fa7a714", & - "14dfaffe9ab7ba93ce8", & - "36652b8b0226f6cc940", & - "777234e72dd631499ac", & - "581964c38824c5a58f8", & - "187cba427974172c6a0", & - "a90588951da0399e6f0", & - "3ddb7427533342f51cc", & - "25d308610cf492a5ac4"/ diff --git a/lib/fst240/ldpc_280_74_parity.f90 b/lib/fst240/ldpc_280_74_parity.f90 deleted file mode 100644 index 302edeb25..000000000 --- a/lib/fst240/ldpc_280_74_parity.f90 +++ /dev/null @@ -1,504 +0,0 @@ -data Mn/ & - 95, 150, 172, & - 154, 178, 184, & - 1, 90, 164, & - 2, 143, 199, & - 3, 33, 70, & - 4, 23, 86, & - 5, 127, 174, & - 6, 18, 110, & - 7, 59, 99, & - 8, 94, 124, & - 9, 168, 206, & - 10, 165, 175, & - 11, 64, 166, & - 12, 103, 156, & - 13, 46, 80, & - 14, 35, 172, & - 15, 20, 189, & - 16, 162, 188, & - 17, 74, 200, & - 19, 52, 178, & - 21, 87, 182, & - 22, 30, 144, & - 24, 37, 126, & - 25, 107, 171, & - 26, 114, 187, & - 27, 36, 53, & - 28, 91, 169, & - 29, 100, 109, & - 31, 71, 192, & - 32, 106, 190, & - 34, 160, 204, & - 38, 93, 136, & - 39, 77, 196, & - 40, 43, 177, & - 41, 56, 66, & - 42, 115, 151, & - 44, 155, 180, & - 45, 105, 128, & - 47, 54, 203, & - 48, 117, 120, & - 49, 62, 183, & - 50, 185, 202, & - 51, 83, 147, & - 55, 75, 170, & - 57, 79, 205, & - 58, 67, 159, & - 60, 81, 201, & - 61, 89, 184, & - 63, 119, 198, & - 65, 104, 152, & - 68, 149, 191, & - 69, 134, 167, & - 72, 102, 129, & - 73, 95, 108, & - 76, 82, 146, & - 78, 112, 173, & - 84, 141, 161, & - 85, 138, 157, & - 92, 132, 145, & - 96, 131, 181, & - 97, 110, 121, & - 98, 133, 153, & - 74, 101, 195, & - 111, 118, 183, & - 113, 130, 163, & - 116, 176, 193, & - 125, 188, 194, & - 135, 142, 148, & - 28, 137, 140, & - 33, 68, 150, & - 46, 51, 179, & - 6, 186, 198, & - 79, 138, 197, & - 1, 30, 122, & - 1, 58, 162, & - 2, 9, 172, & - 3, 71, 161, & - 4, 119, 142, & - 5, 147, 160, & - 6, 73, 183, & - 7, 118, 202, & - 8, 82, 98, & - 2, 47, 56, & - 10, 92, 151, & - 11, 19, 150, & - 12, 169, 179, & - 13, 43, 188, & - 14, 15, 192, & - 14, 82, 120, & - 16, 131, 155, & - 17, 123, 148, & - 18, 60, 117, & - 11, 90, 134, & - 20, 154, 195, & - 21, 47, 166, & - 22, 24, 86, & - 23, 48, 167, & - 21, 22, 190, & - 25, 44, 53, & - 26, 50, 64, & - 4, 27, 95, & - 28, 87, 205, & - 1, 29, 183, & - 30, 132, 185, & - 31, 108, 180, & - 32, 38, 174, & - 33, 36, 128, & - 34, 125, 134, & - 35, 190, 201, & - 30, 33, 142, & - 37, 61, 81, & - 32, 65, 70, & - 39, 40, 41, & - 36, 39, 78, & - 40, 140, 144, & - 42, 100, 194, & - 9, 13, 111, & - 20, 25, 115, & - 45, 140, 165, & - 10, 46, 60, & - 15, 43, 200, & - 23, 113, 158, & - 16, 49, 150, & - 12, 26, 164, & - 51, 88, 115, & - 52, 63, 141, & - 44, 101, 187, & - 34, 54, 173, & - 55, 93, 139, & - 56, 67, 102, & - 57, 62, 152, & - 29, 80, 89, & - 5, 59, 195, & - 18, 100, 156, & - 28, 61, 162, & - 31, 62, 163, & - 38, 52, 103, & - 50, 149, 175, & - 65, 122, 138, & - 66, 112, 171, & - 24, 68, 198, & - 68, 69, 84, & - 51, 69, 108, & - 70, 146, 159, & - 3, 91, 201, & - 72, 143, 149, & - 6, 129, 188, & - 74, 104, 153, & - 54, 75, 186, & - 76, 95, 200, & - 77, 120, 168, & - 41, 104, 182, & - 79, 144, 187, & - 58, 171, 193, & - 37, 85, 135, & - 8, 174, 197, & - 83, 163, 176, & - 53, 67, 184, & - 85, 99, 196, & - 76, 84, 138, & - 77, 87, 194, & - 86, 123, 202, & - 57, 89, 146, & - 27, 90, 97, & - 91, 126, 136, & - 46, 107, 113, & - 55, 189, 204, & - 94, 111, 130, & - 19, 139, 152, & - 96, 121, 158, & - 75, 88, 94, & - 93, 98, 157, & - 79, 81, 203, & - 42, 148, 206, & - 101, 156, 181, & - 97, 114, 154, & - 103, 170, 175, & - 78, 106, 191, & - 105, 109, 135, & - 64, 74, 176, & - 73, 92, 169, & - 80, 132, 181, & - 71, 105, 186, & - 110, 137, 204, & - 21, 159, 192, & - 35, 66, 137, & - 48, 127, 205, & - 114, 182, 193, & - 2, 18, 163, & - 59, 116, 129, & - 99, 107, 119, & - 7, 121, 125, & - 102, 109, 141, & - 19, 87, 160, & - 96, 165, 172, & - 63, 118, 147, & - 17, 143, 196, & - 124, 164, 173, & - 112, 117, 131, & - 52, 151, 180, & - 127, 198, 199, & - 106, 110, 167, & - 116, 177, 178, & - 72, 130, 155, & - 49, 177, 203, & - 128, 133, 166, & - 133, 189, 206, & - 75, 145, 191, & - 1, 51, 133, & - 83, 136, 168, & - 4, 155, 179, & - 3, 127, 157, & - 90, 170, 190, & - 5, 140, 164, & - 6, 139, 196, & - 31, 34, 142, & - 7, 53, 104, & - 11, 39, 109, & - 145, 178, 197, & - 25, 143, 146, & - 8, 134, 181, & - 9, 61, 174, & - 10, 41, 198, & - 12, 135, 159, & - 14, 79, 113, & - 13, 33, 66, & - 153, 161, 188, & - 16, 20, 136, & - 17, 45, 180, & - 22, 100, 116, & - 15, 118, 191, & - 157, 179, 184, & - 37, 110, 185, & - 30, 141, 168, & - 27, 176, 189, & - 28, 76, 186, & - 24, 26, 111, & - 124, 185, 199, & - 45, 122, 126, & - 35, 72, 147, & - 32, 119, 194, & - 36, 50, 138, & - 23, 29, 175, & - 42, 67, 124, & - 40, 89, 94, & - 43, 103, 199, & - 49, 151, 167, & - 44, 84, 204, & - 47, 48, 122, & - 46, 105, 195, & - 55, 96, 177, & - 57, 59, 106, & - 38, 54, 193, & - 58, 86, 152, & - 63, 101, 162, & - 60, 98, 123, & - 64, 115, 205, & - 62, 200, 201, & - 65, 73, 154, & - 56, 82, 183, & - 69, 91, 99, & - 70, 202, 203, & - 74, 112, 197, & - 71, 131, 206, & - 77, 165, 171, & - 68, 97, 120, & - 78, 156, 161, & - 80, 114, 148, & - 83, 92, 187, & - 88, 102, 158, & - 107, 145, 166, & - 122, 125, 130, & - 85, 117, 170, & - 121, 128, 169, & - 126, 129, 173, & - 153, 158, 160, & - 93, 144, 149, & - 88, 123, 137, & - 81, 108, 182, & - 132, 139, 192/ - -data Nm/ & - 3, 74, 75, 103, 209, & - 4, 76, 83, 189, 0, & - 5, 77, 145, 212, 0, & - 6, 78, 101, 211, 0, & - 7, 79, 133, 214, 0, & - 8, 72, 80, 147, 215, & - 9, 81, 192, 217, 0, & - 10, 82, 156, 221, 0, & - 11, 76, 117, 222, 0, & - 12, 84, 120, 223, 0, & - 13, 85, 93, 218, 0, & - 14, 86, 124, 224, 0, & - 15, 87, 117, 226, 0, & - 16, 88, 89, 225, 0, & - 17, 88, 121, 231, 0, & - 18, 90, 123, 228, 0, & - 19, 91, 197, 229, 0, & - 8, 92, 134, 189, 0, & - 20, 85, 169, 194, 0, & - 17, 94, 118, 228, 0, & - 21, 95, 98, 185, 0, & - 22, 96, 98, 230, 0, & - 6, 97, 122, 243, 0, & - 23, 96, 141, 237, 0, & - 24, 99, 118, 220, 0, & - 25, 100, 124, 237, 0, & - 26, 101, 164, 235, 0, & - 27, 69, 102, 135, 236, & - 28, 103, 132, 243, 0, & - 22, 74, 104, 110, 234, & - 29, 105, 136, 216, 0, & - 30, 106, 112, 241, 0, & - 5, 70, 107, 110, 226, & - 31, 108, 128, 216, 0, & - 16, 109, 186, 240, 0, & - 26, 107, 114, 242, 0, & - 23, 111, 155, 233, 0, & - 32, 106, 137, 253, 0, & - 33, 113, 114, 218, 0, & - 34, 113, 115, 245, 0, & - 35, 113, 152, 223, 0, & - 36, 116, 174, 244, 0, & - 34, 87, 121, 246, 0, & - 37, 99, 127, 248, 0, & - 38, 119, 229, 239, 0, & - 15, 71, 120, 166, 250, & - 39, 83, 95, 249, 0, & - 40, 97, 187, 249, 0, & - 41, 123, 205, 247, 0, & - 42, 100, 138, 242, 0, & - 43, 71, 125, 143, 209, & - 20, 126, 137, 200, 0, & - 26, 99, 158, 217, 0, & - 39, 128, 149, 253, 0, & - 44, 129, 167, 251, 0, & - 35, 83, 130, 260, 0, & - 45, 131, 163, 252, 0, & - 46, 75, 154, 254, 0, & - 9, 133, 190, 252, 0, & - 47, 92, 120, 256, 0, & - 48, 111, 135, 222, 0, & - 41, 131, 136, 258, 0, & - 49, 126, 196, 255, 0, & - 13, 100, 180, 257, 0, & - 50, 112, 139, 259, 0, & - 35, 140, 186, 226, 0, & - 46, 130, 158, 244, 0, & - 51, 70, 141, 142, 266, & - 52, 142, 143, 261, 0, & - 5, 112, 144, 262, 0, & - 29, 77, 183, 264, 0, & - 53, 146, 204, 240, 0, & - 54, 80, 181, 259, 0, & - 19, 63, 148, 180, 263, & - 44, 149, 171, 208, 0, & - 55, 150, 160, 236, 0, & - 33, 151, 161, 265, 0, & - 56, 114, 178, 267, 0, & - 45, 73, 153, 173, 225, & - 15, 132, 182, 268, 0, & - 47, 111, 173, 279, 0, & - 55, 82, 89, 260, 0, & - 43, 157, 210, 269, 0, & - 57, 142, 160, 248, 0, & - 58, 155, 159, 273, 0, & - 6, 96, 162, 254, 0, & - 21, 102, 161, 194, 0, & - 125, 171, 270, 278, 0, & - 48, 132, 163, 245, 0, & - 3, 93, 164, 213, 0, & - 27, 145, 165, 261, 0, & - 59, 84, 181, 269, 0, & - 32, 129, 172, 277, 0, & - 10, 168, 171, 245, 0, & - 1, 54, 101, 150, 0, & - 60, 170, 195, 251, 0, & - 61, 164, 176, 266, 0, & - 62, 82, 172, 256, 0, & - 9, 159, 191, 261, 0, & - 28, 116, 134, 230, 0, & - 63, 127, 175, 255, 0, & - 53, 130, 193, 270, 0, & - 14, 137, 177, 246, 0, & - 50, 148, 152, 217, 0, & - 38, 179, 183, 250, 0, & - 30, 178, 202, 252, 0, & - 24, 166, 191, 271, 0, & - 54, 105, 143, 279, 0, & - 28, 179, 193, 218, 0, & - 8, 61, 184, 202, 233, & - 64, 117, 168, 237, 0, & - 56, 140, 199, 263, 0, & - 65, 122, 166, 225, 0, & - 25, 176, 188, 268, 0, & - 36, 118, 125, 257, 0, & - 66, 190, 203, 230, 0, & - 40, 92, 199, 273, 0, & - 64, 81, 196, 231, 0, & - 49, 78, 191, 241, 0, & - 40, 89, 151, 266, 0, & - 61, 170, 192, 274, 0, & - 74, 139, 239, 249, 272, & - 91, 162, 256, 278, 0, & - 10, 198, 238, 244, 0, & - 67, 108, 192, 272, 0, & - 23, 165, 239, 275, 0, & - 7, 187, 201, 212, 0, & - 38, 107, 206, 274, 0, & - 53, 147, 190, 275, 0, & - 65, 168, 204, 272, 0, & - 60, 90, 199, 264, 0, & - 59, 104, 182, 280, 0, & - 62, 206, 207, 209, 0, & - 52, 93, 108, 221, 0, & - 68, 155, 179, 224, 0, & - 32, 165, 210, 228, 0, & - 69, 184, 186, 278, 0, & - 58, 73, 139, 160, 242, & - 129, 169, 215, 280, 0, & - 69, 115, 119, 214, 0, & - 57, 126, 193, 234, 0, & - 68, 78, 110, 216, 0, & - 4, 146, 197, 220, 0, & - 22, 115, 153, 277, 0, & - 59, 208, 219, 271, 0, & - 55, 144, 163, 220, 0, & - 43, 79, 196, 240, 0, & - 68, 91, 174, 268, 0, & - 51, 138, 146, 277, 0, & - 1, 70, 85, 123, 0, & - 36, 84, 200, 247, 0, & - 50, 131, 169, 254, 0, & - 62, 148, 227, 276, 0, & - 2, 94, 176, 259, 0, & - 37, 90, 204, 211, 0, & - 14, 134, 175, 267, 0, & - 58, 172, 212, 232, 0, & - 122, 170, 270, 276, 0, & - 46, 144, 185, 224, 0, & - 31, 79, 194, 276, 0, & - 57, 77, 227, 267, 0, & - 18, 75, 135, 255, 0, & - 65, 136, 157, 189, 0, & - 3, 124, 198, 214, 0, & - 12, 119, 195, 265, 0, & - 13, 95, 206, 271, 0, & - 52, 97, 202, 247, 0, & - 11, 151, 210, 234, 0, & - 27, 86, 181, 274, 0, & - 44, 177, 213, 273, 0, & - 24, 140, 154, 265, 0, & - 1, 16, 76, 195, 0, & - 56, 128, 198, 275, 0, & - 7, 106, 156, 222, 0, & - 12, 138, 177, 243, 0, & - 66, 157, 180, 235, 0, & - 34, 203, 205, 251, 0, & - 2, 20, 203, 219, 0, & - 71, 86, 211, 232, 0, & - 37, 105, 200, 229, 0, & - 60, 175, 182, 221, 0, & - 21, 152, 188, 279, 0, & - 41, 64, 80, 103, 260, & - 2, 48, 158, 232, 0, & - 42, 104, 233, 238, 0, & - 72, 149, 183, 236, 0, & - 25, 127, 153, 269, 0, & - 18, 67, 87, 147, 227, & - 17, 167, 207, 235, 0, & - 30, 98, 109, 213, 0, & - 51, 178, 208, 231, 0, & - 29, 88, 185, 280, 0, & - 66, 154, 188, 253, 0, & - 67, 116, 161, 241, 0, & - 63, 94, 133, 250, 0, & - 33, 159, 197, 215, 0, & - 73, 156, 219, 263, 0, & - 49, 72, 141, 201, 223, & - 4, 201, 238, 246, 0, & - 19, 121, 150, 258, 0, & - 47, 109, 145, 258, 0, & - 42, 81, 162, 262, 0, & - 39, 173, 205, 262, 0, & - 31, 167, 184, 248, 0, & - 45, 102, 187, 257, 0, & - 11, 174, 207, 264, 0/ - -data nrw/ & -5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & -4,4,4,4,4,4,4,5,4,5,4,4,5,4,4,4,4,4,4,4, & -4,4,4,4,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4, & -4,4,4,4,4,4,4,5,4,4,4,4,4,5,4,4,4,4,5,4, & -4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & -4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4, & -4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4, & -4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & -4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & -4,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,4,4, & -4,4,4,4,4,4/ - -ncw=3 diff --git a/lib/fst240/ldpcsim280_101.f90 b/lib/fst240/ldpcsim280_101.f90 deleted file mode 100644 index df5e1f019..000000000 --- a/lib/fst240/ldpcsim280_101.f90 +++ /dev/null @@ -1,139 +0,0 @@ -program ldpcsim280_101 - -! End-to-end test of the (280,101)/crc24 encoder and decoders. - - use packjt77 - - parameter(N=280, K=101, M=N-K) - character*8 arg - character*37 msg0,msg - character*77 c77 - character*24 c24 - integer*1 msgbits(101) - integer*1 apmask(280) - integer*1 cw(280) - integer*1 codeword(N),message101(101) - integer ncrc24 - real rxdata(N),llr(N) - real llrd(280) - logical first,unpk77_success - data first/.true./ - - nargs=iargc() - if(nargs.ne.6 .and. nargs.ne.7) then - print*,'Usage : ldpcsim niter norder maxosd #trials s K [msg]' - print*,'e.g. ldpcsim280_101 20 3 2 1000 0.85 91 "K9AN K1JT FN20"' - print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' - print*,'niter : is the number of BP iterations.' - print*,'norder: -1 is BP only, norder>=0 is OSD order' - print*,'K :is the number of message+CRC bits and must be in the range [77,101]' - print*,'WSPR-format message is optional' - return - endif - call getarg(1,arg) - read(arg,*) max_iterations - call getarg(2,arg) - read(arg,*) norder - call getarg(3,arg) - read(arg,*) maxosd - call getarg(4,arg) - read(arg,*) ntrials - call getarg(5,arg) - read(arg,*) s - call getarg(6,arg) - read(arg,*) Keff - msg0='K9AN K1JT FN20 ' - if(nargs.eq.7) call getarg(7,msg0) - call pack77(msg0,i3,n3,c77) - call unpack77(c77,0,msg,unpk77_success) - if(unpk77_success) then - write(*,1100) msg(1:37) -1100 format('Decoded message: ',a37) - else - print*,'Error unpacking message' - endif - - rate=real(91)/real(N) - - write(*,*) "code rate: ",rate - write(*,*) "niter : ",max_iterations - write(*,*) "norder : ",norder - write(*,*) "s : ",s - write(*,*) "K : ",Keff - - msgbits=0 - read(c77,'(77i1)') msgbits(1:77) - write(*,*) 'message' - write(*,'(77i1)') msgbits(1:77) - - call get_crc24(msgbits,101,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(78:101) - write(*,*) 'message with crc24' - write(*,'(101i1)') msgbits(1:101) - call encode280_101(msgbits,codeword) - call init_random_seed() - call sgran() - - write(*,*) 'codeword' - write(*,'(77i1,1x,24i1,1x,73i1)') codeword - - write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" - do idb = 8,-3,-1 - db=idb/2.0-1.0 - sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No -! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No - ngood=0 - nue=0 - nberr=0 - do itrial=1, ntrials -! Create a realization of a noisy received word - do i=1,N - rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() - enddo - nerr=0 - do i=1,N - if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 - enddo - nberr=nberr+nerr - - rxav=sum(rxdata)/N - rx2av=sum(rxdata*rxdata)/N - rxsig=sqrt(rx2av-rxav*rxav) - rxdata=rxdata/rxsig - if( s .lt. 0 ) then - ss=sigma - else - ss=s - endif - - llr=2.0*rxdata/(ss*ss) - apmask=0 -! max_iterations is max number of belief propagation iterations - call bpdecode280_101(llr,apmask,max_iterations,message101,cw,nharderror,niterations,nchecks) - dmin=0.0 - if( (nharderror .lt. 0) .and. (norder .ge. 0) ) then -! call osd280_101(llr, Keff, apmask, norder, message101, cw, nharderror, dmin) - call decode280_101(llr, Keff, maxosd, norder, apmask, message101, cw, ntype, nharderror, dmin) - endif - - if(nharderror.ge.0) then - n2err=0 - do i=1,N - if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 - enddo - if(n2err.eq.0) then - ngood=ngood+1 - else - nue=nue+1 - endif - endif - enddo -! snr2500=db+10*log10(200.0/116.0/2500.0) - esn0=db+10*log10(rate) - pberr=real(nberr)/(real(ntrials*N)) - write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr - - enddo - -end program ldpcsim280_101 diff --git a/lib/fst240/ldpcsim280_74.f90 b/lib/fst240/ldpcsim280_74.f90 deleted file mode 100644 index 8953973e9..000000000 --- a/lib/fst240/ldpcsim280_74.f90 +++ /dev/null @@ -1,132 +0,0 @@ -program ldpcsim280_74 - -! End-to-end test of the (280,74)/crc24 encoder and decoders. - - use packjt77 - - parameter(N=280, K=74, M=N-K) - character*8 arg - character*37 msg0,msg - character*77 c77 - character*24 c24 - integer*1 msgbits(74) - integer*1 apmask(280) - integer*1 cw(280) - integer*1 codeword(N),message74(74) - integer ncrc24 - real rxdata(N),llr(N) - real llrd(280) - logical first,unpk77_success - data first/.true./ - - nargs=iargc() - if(nargs.ne.5 .and. nargs.ne.6) then - print*,'Usage: ldpcsim norder maxosd #trials s K [msg]' - print*,'e.g. ldpcsim280_74 3 2 1000 0.85 91 "K9AN K1JT FN20"' - print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' - print*,'niter: is the number of BP iterations.' - print*,'norder: -1 is BP only, norder>=0 is OSD order' - print*,'maxosd: number of calls to OSD' - print*,'K :is the number of message+CRC bits and must be in the range [50,74]' - print*,'WSPR-format message is optional' - return - endif - call getarg(1,arg) - read(arg,*) norder - call getarg(2,arg) - read(arg,*) maxosd - call getarg(3,arg) - read(arg,*) ntrials - call getarg(4,arg) - read(arg,*) s - call getarg(5,arg) - read(arg,*) Keff - msg0='K9AN K1JT FN20 ' - if(nargs.eq.6) call getarg(6,msg0) - call pack77(msg0,i3,n3,c77) - call unpack77(c77,0,msg,unpk77_success) - if(unpk77_success) then - write(*,1100) msg(1:37) -1100 format('Decoded message: ',a37) - else - print*,'Error unpacking message' - endif - - rate=real(64)/real(N) - - write(*,*) "code rate: ",rate - write(*,*) "norder : ",norder - write(*,*) "s : ",s - write(*,*) "K : ",Keff - - msgbits=0 - read(c77,'(50i1)') msgbits(1:50) - write(*,*) 'message' - write(*,'(50i1)') msgbits(1:50) - - msgbits(51:74)=0 - call get_crc24(msgbits,74,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(51:74) - write(*,*) 'message with crc24' - write(*,'(74i1)') msgbits(1:74) - call encode280_74(msgbits,codeword) - call init_random_seed() - call sgran() - - write(*,*) 'codeword' - write(*,'(50i1,1x,24i1,1x,206i1)') codeword - - write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" - do idb = 2,-2,-1 - db=idb/2.0-1.0 - sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No -! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No - ngood=0 - nue=0 - nberr=0 - do itrial=1, ntrials -! Create a realization of a noisy received word - do i=1,N - rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() - enddo - nerr=0 - do i=1,N - if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 - enddo - nberr=nberr+nerr - - rxav=sum(rxdata)/N - rx2av=sum(rxdata*rxdata)/N - rxsig=sqrt(rx2av-rxav*rxav) - rxdata=rxdata/rxsig - if( s .lt. 0 ) then - ss=sigma - else - ss=s - endif - - llr=2.0*rxdata/(ss*ss) - apmask=0 - call decode280_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharderror,dmin) - - if(nharderror.ge.0) then - n2err=0 - do i=1,N - if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 - enddo - if(n2err.eq.0) then - ngood=ngood+1 - else - nue=nue+1 - endif - endif - enddo -! snr2500=db+10*log10(200.0/116.0/2500.0) - esn0=db+10*log10(rate) - pberr=real(nberr)/(real(ntrials*N)) - write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr - - enddo - -end program ldpcsim280_74 diff --git a/lib/fst240/osd280_101.f90 b/lib/fst240/osd280_101.f90 deleted file mode 100644 index acea3f664..000000000 --- a/lib/fst240/osd280_101.f90 +++ /dev/null @@ -1,403 +0,0 @@ -subroutine osd280_101(llr,k,apmask,ndeep,message101,cw,nhardmin,dmin) -! -! An ordered-statistics decoder for the (280,101) code. -! Message payload is 77 bits. Any or all of a 24-bit CRC can be -! used for detecting incorrect codewords. The remaining CRC bits are -! cascaded with the LDPC code for the purpose of improving the -! distance spectrum of the code. -! -! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are -! to be used for bad codeword detection, then the argument k should -! be set to 77+p1. -! -! Valid values for k are in the range [77,101]. -! - character*24 c24 - integer, parameter:: N=280 - integer*1 apmask(N),apmaskr(N) - integer*1, allocatable, save :: gen(:,:) - integer*1, allocatable :: genmrb(:,:),g2(:,:) - integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) - integer*1, allocatable :: r2pat(:) - integer indices(N),nxor(N) - integer*1 cw(N),ce(N),c0(N),hdec(N) - integer*1, allocatable :: decoded(:) - integer*1 message101(101) - integer indx(N) - real llr(N),rx(N),absrx(N) - - logical first,reset - data first/.true./ - save first - - allocate( genmrb(k,N), g2(N,k) ) - allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) - allocate( r2pat(N-k), decoded(k) ) - - if( first ) then ! fill the generator matrix -! -! Create generator matrix for partial CRC cascaded with LDPC code. -! -! Let p2=101-k and p1+p2=24. -! -! The last p2 bits of the CRC24 are cascaded with the LDPC code. -! -! The first p1=k-77 CRC24 bits will be used for error detection. -! - allocate( gen(k,N) ) - gen=0 - do i=1,k - message101=0 - message101(i)=1 - if(i.le.77) then - call get_crc24(message101,101,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') message101(78:101) - message101(78:k)=0 - endif - call encode280_101(message101,cw) - gen(i,:)=cw - enddo - - first=.false. - endif - - rx=llr - apmaskr=apmask - -! Hard decisions on the received word. - hdec=0 - where(rx .ge. 0) hdec=1 - -! Use magnitude of received symbols as a measure of reliability. - absrx=abs(rx) - call indexx(absrx,N,indx) - -! Re-order the columns of the generator matrix in order of decreasing reliability. - do i=1,N - genmrb(1:k,i)=gen(1:k,indx(N+1-i)) - indices(i)=indx(N+1-i) - enddo - -! Do gaussian elimination to create a generator matrix with the most reliable -! received bits in positions 1:k in order of decreasing reliability (more or less). - do id=1,k ! diagonal element indices - do icol=id,k+20 ! The 20 is ad hoc - beware - iflag=0 - if( genmrb(id,icol) .eq. 1 ) then - iflag=1 - if( icol .ne. id ) then ! reorder column - temp(1:k)=genmrb(1:k,id) - genmrb(1:k,id)=genmrb(1:k,icol) - genmrb(1:k,icol)=temp(1:k) - itmp=indices(id) - indices(id)=indices(icol) - indices(icol)=itmp - endif - do ii=1,k - if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then - genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) - endif - enddo - exit - endif - enddo - enddo - - g2=transpose(genmrb) - -! The hard decisions for the k MRB bits define the order 0 message, m0. -! Encode m0 using the modified generator matrix to find the "order 0" codeword. -! Flip various combinations of bits in m0 and re-encode to generate a list of -! codewords. Return the member of the list that has the smallest Euclidean -! distance to the received word. - - hdec=hdec(indices) ! hard decisions from received symbols - m0=hdec(1:k) ! zero'th order message - absrx=absrx(indices) - rx=rx(indices) - apmaskr=apmaskr(indices) - - call mrbencode101(m0,c0,g2,N,k) - nxor=ieor(c0,hdec) - nhardmin=sum(nxor) - dmin=sum(nxor*absrx) - - cw=c0 - ntotal=0 - nrejected=0 - npre1=0 - npre2=0 - - if(ndeep.eq.0) goto 998 ! norder=0 - if(ndeep.gt.6) ndeep=6 - if( ndeep.eq. 1) then - nord=1 - npre1=0 - npre2=0 - nt=40 - ntheta=12 - elseif(ndeep.eq.2) then - nord=1 - npre1=1 - npre2=0 - nt=40 - ntheta=12 - elseif(ndeep.eq.3) then - nord=1 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=14 - elseif(ndeep.eq.4) then - nord=2 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=17 - elseif(ndeep.eq.5) then - nord=3 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=15 - elseif(ndeep.eq.6) then - nord=4 - npre1=1 - npre2=1 - nt=95 - ntheta=12 - ntau=15 - endif - - do iorder=1,nord - misub(1:k-iorder)=0 - misub(k-iorder+1:k)=1 - iflag=k-iorder+1 - do while(iflag .ge.0) - if(iorder.eq.nord .and. npre1.eq.0) then - iend=iflag - else - iend=1 - endif - d1=0. - do n1=iflag,iend,-1 - mi=misub - mi(n1)=1 - if(any(iand(apmaskr(1:k),mi).eq.1)) cycle - ntotal=ntotal+1 - me=ieor(m0,mi) - if(n1.eq.iflag) then - call mrbencode101(me,ce,g2,N,k) - e2sub=ieor(ce(k+1:N),hdec(k+1:N)) - e2=e2sub - nd1kpt=sum(e2sub(1:nt))+1 - d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) - else - e2=ieor(e2sub,g2(k+1:N,n1)) - nd1kpt=sum(e2(1:nt))+2 - endif - if(nd1kpt .le. ntheta) then - call mrbencode101(me,ce,g2,N,k) - nxor=ieor(ce,hdec) - if(n1.eq.iflag) then - dd=d1+sum(e2sub*absrx(k+1:N)) - else - dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) - endif - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - nd1kptbest=nd1kpt - endif - else - nrejected=nrejected+1 - endif - enddo -! Get the next test error pattern, iflag will go negative -! when the last pattern with weight iorder has been generated. - call nextpat101(misub,k,iorder,iflag) - enddo - enddo - - if(npre2.eq.1) then - reset=.true. - ntotal=0 - do i1=k,1,-1 - do i2=i1-1,1,-1 - ntotal=ntotal+1 - mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) - call boxit101(reset,mi(1:ntau),ntau,ntotal,i1,i2) - enddo - enddo - - ncount2=0 - ntotal2=0 - reset=.true. -! Now run through again and do the second pre-processing rule - misub(1:k-nord)=0 - misub(k-nord+1:k)=1 - iflag=k-nord+1 - do while(iflag .ge.0) - me=ieor(m0,misub) - call mrbencode101(me,ce,g2,N,k) - e2sub=ieor(ce(k+1:N),hdec(k+1:N)) - do i2=0,ntau - ntotal2=ntotal2+1 - ui=0 - if(i2.gt.0) ui(i2)=1 - r2pat=ieor(e2sub,ui) -778 continue - call fetchit101(reset,r2pat(1:ntau),ntau,in1,in2) - if(in1.gt.0.and.in2.gt.0) then - ncount2=ncount2+1 - mi=misub - mi(in1)=1 - mi(in2)=1 - if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle - me=ieor(m0,mi) - call mrbencode101(me,ce,g2,N,k) - nxor=ieor(ce,hdec) - dd=sum(nxor*absrx) - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - endif - goto 778 - endif - enddo - call nextpat101(misub,k,nord,iflag) - enddo - endif - -998 continue -! Re-order the codeword to [message bits][parity bits] format. - cw(indices)=cw - hdec(indices)=hdec - message101=cw(1:101) - call get_crc24(message101,101,nbadcrc) - if(nbadcrc.ne.0) nhardmin=-nhardmin - - return -end subroutine osd280_101 - -subroutine mrbencode101(me,codeword,g2,N,K) - integer*1 me(K),codeword(N),g2(N,K) -! fast encoding for low-weight test patterns - codeword=0 - do i=1,K - if( me(i) .eq. 1 ) then - codeword=ieor(codeword,g2(1:N,i)) - endif - enddo - return -end subroutine mrbencode101 - -subroutine nextpat101(mi,k,iorder,iflag) - integer*1 mi(k),ms(k) -! generate the next test error pattern - ind=-1 - do i=1,k-1 - if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i - enddo - if( ind .lt. 0 ) then ! no more patterns of this order - iflag=ind - return - endif - ms=0 - ms(1:ind-1)=mi(1:ind-1) - ms(ind)=1 - ms(ind+1)=0 - if( ind+1 .lt. k ) then - nz=iorder-sum(ms) - ms(k-nz+1:k)=1 - endif - mi=ms - do i=1,k ! iflag will point to the lowest-index 1 in mi - if(mi(i).eq.1) then - iflag=i - exit - endif - enddo - return -end subroutine nextpat101 - -subroutine boxit101(reset,e2,ntau,npindex,i1,i2) - integer*1 e2(1:ntau) - integer indexes(5000,2),fp(0:525000),np(5000) - logical reset - common/boxes/indexes,fp,np - - if(reset) then - patterns=-1 - fp=-1 - np=-1 - sc=-1 - indexes=-1 - reset=.false. - endif - - indexes(npindex,1)=i1 - indexes(npindex,2)=i2 - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - - ip=fp(ipat) ! see what's currently stored in fp(ipat) - if(ip.eq.-1) then - fp(ipat)=npindex - else - do while (np(ip).ne.-1) - ip=np(ip) - enddo - np(ip)=npindex - endif - return -end subroutine boxit101 - -subroutine fetchit101(reset,e2,ntau,i1,i2) - integer indexes(5000,2),fp(0:525000),np(5000) - integer lastpat - integer*1 e2(ntau) - logical reset - common/boxes/indexes,fp,np - save lastpat,inext - - if(reset) then - lastpat=-1 - reset=.false. - endif - - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - index=fp(ipat) - - if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices - i1=indexes(index,1) - i2=indexes(index,2) - inext=np(index) - elseif(lastpat.eq.ipat .and. inext.gt.0) then - i1=indexes(inext,1) - i2=indexes(inext,2) - inext=np(inext) - else - i1=-1 - i2=-1 - inext=-1 - endif - lastpat=ipat - return -end subroutine fetchit101 - diff --git a/lib/fst240/osd280_74.f90 b/lib/fst240/osd280_74.f90 deleted file mode 100644 index 6f87dd216..000000000 --- a/lib/fst240/osd280_74.f90 +++ /dev/null @@ -1,403 +0,0 @@ -subroutine osd280_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin) -! -! An ordered-statistics decoder for the (280,74) code. -! Message payload is 50 bits. Any or all of a 24-bit CRC can be -! used for detecting incorrect codewords. The remaining CRC bits are -! cascaded with the LDPC code for the purpose of improving the -! distance spectrum of the code. -! -! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are -! to be used for bad codeword detection, then the argument k should -! be set to 50+p1. -! -! Valid values for k are in the range [50,74]. -! - character*24 c24 - integer, parameter:: N=280 - integer*1 apmask(N),apmaskr(N) - integer*1, allocatable, save :: gen(:,:) - integer*1, allocatable :: genmrb(:,:),g2(:,:) - integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) - integer*1, allocatable :: r2pat(:) - integer indices(N),nxor(N) - integer*1 cw(N),ce(N),c0(N),hdec(N) - integer*1, allocatable :: decoded(:) - integer*1 message74(74) - integer indx(N) - real llr(N),rx(N),absrx(N) - - logical first,reset - data first/.true./ - save first - - allocate( genmrb(k,N), g2(N,k) ) - allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) - allocate( r2pat(N-k), decoded(k) ) - - if( first ) then ! fill the generator matrix -! -! Create generator matrix for partial CRC cascaded with LDPC code. -! -! Let p2=74-k and p1+p2=24. -! -! The last p2 bits of the CRC24 are cascaded with the LDPC code. -! -! The first p1=k-50 CRC24 bits will be used for error detection. -! - allocate( gen(k,N) ) - gen=0 - do i=1,k - message74=0 - message74(i)=1 - if(i.le.50) then - call get_crc24(message74,74,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') message74(51:74) - message74(51:k)=0 - endif - call encode280_74(message74,cw) - gen(i,:)=cw - enddo - - first=.false. - endif - - rx=llr - apmaskr=apmask - -! Hard decisions on the received word. - hdec=0 - where(rx .ge. 0) hdec=1 - -! Use magnitude of received symbols as a measure of reliability. - absrx=abs(rx) - call indexx(absrx,N,indx) - -! Re-order the columns of the generator matrix in order of decreasing reliability. - do i=1,N - genmrb(1:k,i)=gen(1:k,indx(N+1-i)) - indices(i)=indx(N+1-i) - enddo - -! Do gaussian elimination to create a generator matrix with the most reliable -! received bits in positions 1:k in order of decreasing reliability (more or less). - do id=1,k ! diagonal element indices - do icol=id,k+20 ! The 20 is ad hoc - beware - iflag=0 - if( genmrb(id,icol) .eq. 1 ) then - iflag=1 - if( icol .ne. id ) then ! reorder column - temp(1:k)=genmrb(1:k,id) - genmrb(1:k,id)=genmrb(1:k,icol) - genmrb(1:k,icol)=temp(1:k) - itmp=indices(id) - indices(id)=indices(icol) - indices(icol)=itmp - endif - do ii=1,k - if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then - genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) - endif - enddo - exit - endif - enddo - enddo - - g2=transpose(genmrb) - -! The hard decisions for the k MRB bits define the order 0 message, m0. -! Encode m0 using the modified generator matrix to find the "order 0" codeword. -! Flip various combinations of bits in m0 and re-encode to generate a list of -! codewords. Return the member of the list that has the smallest Euclidean -! distance to the received word. - - hdec=hdec(indices) ! hard decisions from received symbols - m0=hdec(1:k) ! zero'th order message - absrx=absrx(indices) - rx=rx(indices) - apmaskr=apmaskr(indices) - - call mrbencode74(m0,c0,g2,N,k) - nxor=ieor(c0,hdec) - nhardmin=sum(nxor) - dmin=sum(nxor*absrx) - - cw=c0 - ntotal=0 - nrejected=0 - npre1=0 - npre2=0 - - if(ndeep.eq.0) goto 998 ! norder=0 - if(ndeep.gt.6) ndeep=6 - if( ndeep.eq. 1) then - nord=1 - npre1=0 - npre2=0 - nt=40 - ntheta=12 - elseif(ndeep.eq.2) then - nord=1 - npre1=1 - npre2=0 - nt=40 - ntheta=12 - elseif(ndeep.eq.3) then - nord=1 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=14 - elseif(ndeep.eq.4) then - nord=2 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=17 - elseif(ndeep.eq.5) then - nord=3 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=19 - elseif(ndeep.eq.6) then - nord=4 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=19 - endif - - do iorder=1,nord - misub(1:k-iorder)=0 - misub(k-iorder+1:k)=1 - iflag=k-iorder+1 - do while(iflag .ge.0) - if(iorder.eq.nord .and. npre1.eq.0) then - iend=iflag - else - iend=1 - endif - d1=0. - do n1=iflag,iend,-1 - mi=misub - mi(n1)=1 - if(any(iand(apmaskr(1:k),mi).eq.1)) cycle - ntotal=ntotal+1 - me=ieor(m0,mi) - if(n1.eq.iflag) then - call mrbencode74(me,ce,g2,N,k) - e2sub=ieor(ce(k+1:N),hdec(k+1:N)) - e2=e2sub - nd1kpt=sum(e2sub(1:nt))+1 - d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) - else - e2=ieor(e2sub,g2(k+1:N,n1)) - nd1kpt=sum(e2(1:nt))+2 - endif - if(nd1kpt .le. ntheta) then - call mrbencode74(me,ce,g2,N,k) - nxor=ieor(ce,hdec) - if(n1.eq.iflag) then - dd=d1+sum(e2sub*absrx(k+1:N)) - else - dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) - endif - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - nd1kptbest=nd1kpt - endif - else - nrejected=nrejected+1 - endif - enddo -! Get the next test error pattern, iflag will go negative -! when the last pattern with weight iorder has been generated. - call nextpat74(misub,k,iorder,iflag) - enddo - enddo - - if(npre2.eq.1) then - reset=.true. - ntotal=0 - do i1=k,1,-1 - do i2=i1-1,1,-1 - ntotal=ntotal+1 - mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) - call boxit74(reset,mi(1:ntau),ntau,ntotal,i1,i2) - enddo - enddo - - ncount2=0 - ntotal2=0 - reset=.true. -! Now run through again and do the second pre-processing rule - misub(1:k-nord)=0 - misub(k-nord+1:k)=1 - iflag=k-nord+1 - do while(iflag .ge.0) - me=ieor(m0,misub) - call mrbencode74(me,ce,g2,N,k) - e2sub=ieor(ce(k+1:N),hdec(k+1:N)) - do i2=0,ntau - ntotal2=ntotal2+1 - ui=0 - if(i2.gt.0) ui(i2)=1 - r2pat=ieor(e2sub,ui) -778 continue - call fetchit74(reset,r2pat(1:ntau),ntau,in1,in2) - if(in1.gt.0.and.in2.gt.0) then - ncount2=ncount2+1 - mi=misub - mi(in1)=1 - mi(in2)=1 - if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle - me=ieor(m0,mi) - call mrbencode74(me,ce,g2,N,k) - nxor=ieor(ce,hdec) - dd=sum(nxor*absrx) - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - endif - goto 778 - endif - enddo - call nextpat74(misub,k,nord,iflag) - enddo - endif - -998 continue -! Re-order the codeword to [message bits][parity bits] format. - cw(indices)=cw - hdec(indices)=hdec - message74=cw(1:74) - call get_crc24(message74,74,nbadcrc) - if(nbadcrc.ne.0) nhardmin=-nhardmin - - return -end subroutine osd280_74 - -subroutine mrbencode74(me,codeword,g2,N,K) - integer*1 me(K),codeword(N),g2(N,K) -! fast encoding for low-weight test patterns - codeword=0 - do i=1,K - if( me(i) .eq. 1 ) then - codeword=ieor(codeword,g2(1:N,i)) - endif - enddo - return -end subroutine mrbencode74 - -subroutine nextpat74(mi,k,iorder,iflag) - integer*1 mi(k),ms(k) -! generate the next test error pattern - ind=-1 - do i=1,k-1 - if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i - enddo - if( ind .lt. 0 ) then ! no more patterns of this order - iflag=ind - return - endif - ms=0 - ms(1:ind-1)=mi(1:ind-1) - ms(ind)=1 - ms(ind+1)=0 - if( ind+1 .lt. k ) then - nz=iorder-sum(ms) - ms(k-nz+1:k)=1 - endif - mi=ms - do i=1,k ! iflag will point to the lowest-index 1 in mi - if(mi(i).eq.1) then - iflag=i - exit - endif - enddo - return -end subroutine nextpat74 - -subroutine boxit74(reset,e2,ntau,npindex,i1,i2) - integer*1 e2(1:ntau) - integer indexes(5000,2),fp(0:525000),np(5000) - logical reset - common/boxes/indexes,fp,np - - if(reset) then - patterns=-1 - fp=-1 - np=-1 - sc=-1 - indexes=-1 - reset=.false. - endif - - indexes(npindex,1)=i1 - indexes(npindex,2)=i2 - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - - ip=fp(ipat) ! see what's currently stored in fp(ipat) - if(ip.eq.-1) then - fp(ipat)=npindex - else - do while (np(ip).ne.-1) - ip=np(ip) - enddo - np(ip)=npindex - endif - return -end subroutine boxit74 - -subroutine fetchit74(reset,e2,ntau,i1,i2) - integer indexes(5000,2),fp(0:525000),np(5000) - integer lastpat - integer*1 e2(ntau) - logical reset - common/boxes/indexes,fp,np - save lastpat,inext - - if(reset) then - lastpat=-1 - reset=.false. - endif - - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - index=fp(ipat) - - if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices - i1=indexes(index,1) - i2=indexes(index,2) - inext=np(index) - elseif(lastpat.eq.ipat .and. inext.gt.0) then - i1=indexes(inext,1) - i2=indexes(inext,2) - inext=np(inext) - else - i1=-1 - i2=-1 - inext=-1 - endif - lastpat=ipat - return -end subroutine fetchit74 - From cd9146e646cf7023ff77a43166c97fc31b58a328 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 27 Jun 2020 13:07:11 -0400 Subject: [PATCH 076/239] Change a few more GUI parameters for the switch from FST280 to FST240. Tx timing probably still needs work. --- widgets/mainwindow.cpp | 14 +++++++------- widgets/mainwindow.ui | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 40c94143d..269fdc75f 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1342,8 +1342,8 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST240" or m_mode=="FST240W") { - int stop[] = {45,87,192,397,1012}; - int stop_EME[] = {51,96,201,406,1021}; + int stop[] = {44,85,187,387,987}; + int stop_EME[] = {51,95,197,396,997}; int i=0; if(m_TRperiod==30) i=1; if(m_TRperiod==60) i=2; @@ -3538,11 +3538,11 @@ void MainWindow::guiUpdate() if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR if(m_modeTx=="FST240" or m_mode=="FST240W") { //FST240, FST240W - if(m_TRperiod==15) txDuration=1.0 + 166*800/12000.0; - if(m_TRperiod==30) txDuration=1.0 + 166*1680/12000.0; - if(m_TRperiod==60) txDuration=1.0 + 166*3888/12000.0; - if(m_TRperiod==120) txDuration=1.0 + 166*8200/12000.0; - if(m_TRperiod==300) txDuration=1.0 + 166*21168/12000.0; + if(m_TRperiod==15) txDuration=1.0 + 160*800/12000.0; + if(m_TRperiod==30) txDuration=1.0 + 160*1680/12000.0; + if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; + if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0; + if(m_TRperiod==300) txDuration=1.0 + 160*21168/12000.0; } if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index b635ee21a..b45784cf0 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -1608,7 +1608,7 @@ When not checked you can view the calibration results. QTabWidget::Triangular - 2 + 0 From eb167b11d34151a50cac120df89dc935545e4476 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 27 Jun 2020 14:13:59 -0400 Subject: [PATCH 077/239] Fix several more GUI parameters for FST240. --- lib/fst240/gen_fst240wave.f90 | 7 ------- widgets/mainwindow.cpp | 5 ++--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst240/gen_fst240wave.f90 index 3005968b2..0df62c1b7 100644 --- a/lib/fst240/gen_fst240wave.f90 +++ b/lib/fst240/gen_fst240wave.f90 @@ -8,13 +8,11 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & real, allocatable :: dphi(:) integer hmod integer itone(nsym) -! integer*8 count0,count1,clkfreq logical first data first/.true./ data nsps0/-99/ save first,twopi,dt,tsym,nsps0,ctab -! call system_clock(count0,clkfreq) if(first) then twopi=8.0*atan(1.0) do i=0,NTAB-1 @@ -88,11 +86,6 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 cwave=cshift(cwave,kshift) endif - -! call system_clock(count1,clkfreq) -! tt=float(count1-count0)/float(clkfreq) -! write(*,3001) tt -!3001 format('Tgen:',f8.3) return end subroutine gen_fst240wave diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 269fdc75f..575d43202 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3888,12 +3888,11 @@ void MainWindow::guiUpdate() if(m_TRperiod==120) nsps=8200; if(m_TRperiod==300) nsps=21168; nsps=4*nsps; //48000 Hz sampling - int nsym=164; + int nsym=160; float fsample=48000.0; float dfreq=hmod*fsample/nsps; float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; -// int nwave=(nsym+2)*nsps; - int nwave=48000 + 166*nsps; + int nwave=48000 + (nsym+2)*nsps; int icmplx=0; gen_fst240wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); From 1f16beeafe3b37618ac14e1f1b3c571e7763c554 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 27 Jun 2020 14:11:37 -0500 Subject: [PATCH 078/239] Make T/R=300s work from the command line. --- lib/fst240/fst240sim.f90 | 2 +- lib/fst240_decode.f90 | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index 842e32876..9cca82504 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -51,7 +51,7 @@ program fst240sim if(nsec.eq.30) nsps=1680 if(nsec.eq.60) nsps=3888 if(nsec.eq.120) nsps=8200 - if(nsec.eq.300) nsps=21168 + if(nsec.eq.300) nsps=21504 if(nsps.eq.0) then print*,'Invalid TR sequence length.' go to 999 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 231e00e84..b857e3dc1 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -155,7 +155,7 @@ contains ! The size of the downsampled c2 array is nfft2=nfft1/ndown call fst240_downsample(c_bigfft,nfft1,ndown,fc0,c2) - + call timer('sync240 ',0) do isync=0,1 if(isync.eq.0) then @@ -376,7 +376,7 @@ write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & integer hmod,isyncword(0:7) real f0save data isyncword/0,1,3,2,1,0,2,3/ - data first/.true./,f0save/0.0/,nss0/-1/ + data first/.true./,f0save/-99.9/,nss0/-1/ save first,twopi,dt,fac,f0save,nss0 p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power @@ -444,7 +444,6 @@ write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & s4=s4+abs(z4)/(8*nss) s5=s5+abs(z5)/(8*nss) enddo - sync = s1+s2+s3+s4+s5 return From 51447ef1d3b0b42dabae31af0f82bde73795d2b9 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 27 Jun 2020 16:24:11 -0400 Subject: [PATCH 079/239] Remove the 1 s offset in wave() array. Fix NSPS for 300 s periods. --- Modulator/Modulator.cpp | 24 ++++++++---------------- lib/fst240/gen_fst240wave.f90 | 10 ++++++++-- widgets/mainwindow.cpp | 8 ++++---- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index 3a33c42f1..f267022e0 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -92,20 +92,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, if(delay_ms >= mstr) m_silentFrames = m_ic + 0.001*(delay_ms-mstr)*m_frameRate; } - // Special case for FST280: -// qDebug() << "aa" << m_ic << m_silentFrames << m_symbolsLength << m_nsps; - if(m_nsps==800 or m_nsps==1680 or m_nsps==3888 or m_nsps==8200 or m_nsps==21168) { - m_ic = m_ic + 48000 - 2*m_nsps + 9600; //The 9600 is empirical - m_silentFrames = m_silentFrames - 2*m_nsps; - } - if(m_silentFrames<0) { - m_ic = m_ic - m_silentFrames; - m_silentFrames = 0; - } -// qDebug() << "bb" << m_ic << m_silentFrames; -// qDebug() << "cc" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") -// << delay_ms << mstr << m_silentFrames << m_ic; - +// qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") +// << delay_ms << mstr << m_silentFrames << m_ic << m_symbolsLength; initialize (QIODevice::ReadOnly, channel); Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? @@ -317,14 +305,18 @@ qint64 Modulator::readData (char * data, qint64 maxSize) m_amp=32767.0; sample=qRound(m_amp*foxcom_.wave[m_ic]); } - +/* + if((m_ic<1000 or (4*m_symbolsLength*m_nsps - m_ic) < 1000) and (m_ic%10)==0) { + qDebug() << "cc" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") << m_ic << sample; + } +*/ samples = load(postProcessSample(sample), samples); ++framesGenerated; ++m_ic; } // qDebug() << "dd" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") -// << m_ic << m_amp << foxcom_.wave[m_ic]; +// << m_ic << i1 << foxcom_.wave[m_ic] << framesGenerated; if (m_amp == 0.0) { // TODO G4WJS: compare double with zero might not be wise if (icw[0] == 0) { diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst240/gen_fst240wave.f90 index 0df62c1b7..43170638d 100644 --- a/lib/fst240/gen_fst240wave.f90 +++ b/lib/fst240/gen_fst240wave.f90 @@ -66,7 +66,7 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & enddo ! Compute the ramp-up and ramp-down symbols - kshift=nsps-nint(fsample) + kshift=nsps if(icmplx.eq.0) then wave(1:nsps)=0.0 wave(nsps+1:nsps+nsps/4)=wave(nsps+1:nsps+nsps/4) * & @@ -86,6 +86,12 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 cwave=cshift(cwave,kshift) endif - + +! do i=1,nwave +! write(71,3071) i,i/48000.0,wave(i) +!3071 format(i10,2f15.9) +! enddo + wave(nsps*nsym:)=0. !Kill a stray spike ?? + return end subroutine gen_fst240wave diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 575d43202..e7042b59a 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3542,7 +3542,7 @@ void MainWindow::guiUpdate() if(m_TRperiod==30) txDuration=1.0 + 160*1680/12000.0; if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0; - if(m_TRperiod==300) txDuration=1.0 + 160*21168/12000.0; + if(m_TRperiod==300) txDuration=1.0 + 160*21504/12000.0; } if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 @@ -3886,13 +3886,13 @@ void MainWindow::guiUpdate() if(m_TRperiod==30) nsps=1680; if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; - if(m_TRperiod==300) nsps=21168; + if(m_TRperiod==300) nsps=21504; nsps=4*nsps; //48000 Hz sampling int nsym=160; float fsample=48000.0; float dfreq=hmod*fsample/nsps; float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; - int nwave=48000 + (nsym+2)*nsps; + int nwave=(nsym+2)*nsps; int icmplx=0; gen_fst240wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); @@ -7169,7 +7169,7 @@ void MainWindow::transmit (double snr) if(m_TRperiod==30) nsps=1680; if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; - if(m_TRperiod==300) nsps=21168; + if(m_TRperiod==300) nsps=21504; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; From 89c81cb5f1200a40da5f189a226daa4b76532748 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 27 Jun 2020 15:43:14 -0500 Subject: [PATCH 080/239] XOR the message with rvec before calculating CRC --- lib/fst240/genfst240.f90 | 2 +- lib/fst240_decode.f90 | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/fst240/genfst240.f90 b/lib/fst240/genfst240.f90 index 4cf688308..b442b3efa 100644 --- a/lib/fst240/genfst240.f90 +++ b/lib/fst240/genfst240.f90 @@ -54,6 +54,7 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) read(c24,'(24i1)') msgbits(51:74) else read(c77,'(77i1)') msgbits(1:77) + msgbits(1:77)=mod(msgbits(1:77)+rvec,2) call get_crc24(msgbits,101,ncrc24) write(c24,'(b24.24)') ncrc24 read(c24,'(24i1)') msgbits(78:101) @@ -69,7 +70,6 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) 2 continue - call encode240_101(msgbits,codeword) ! Grayscale mapping: diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index b857e3dc1..c68997bde 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -51,8 +51,12 @@ contains integer*1 apmask(240),cw(240) integer*1 hbits(320) integer*1 message101(101),message74(74) + integer*1 rvec(77) logical badsync,unpk77_success,single_decode integer*2 iwave(300*12000) + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ this%callback => callback hmod=2**nsubmode @@ -313,7 +317,7 @@ contains endif if(nharderrors .ge.0) then if(iwspr.eq.0) then - write(c77,'(77i1)') message101(1:77) + write(c77,'(77i1)') mod(message101(1:77)+rvec,2) call unpack77(c77,0,msg,unpk77_success) else write(c77,'(50i1)') message74(1:50) From 2b85c70bbc3abe77ef88fbadac0ed09b8d156644 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 27 Jun 2020 16:58:55 -0400 Subject: [PATCH 081/239] Correct the m_hsymStop values for FST240-300. --- widgets/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index e7042b59a..645d7c810 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1342,8 +1342,8 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST240" or m_mode=="FST240W") { - int stop[] = {44,85,187,387,987}; - int stop_EME[] = {51,95,197,396,997}; + int stop[] = {44,85,187,387,1003}; + int stop_EME[] = {51,95,197,396,1012}; int i=0; if(m_TRperiod==30) i=1; if(m_TRperiod==60) i=2; From f774cecd000fc90f940f46cd46625318d5a2554f Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sun, 28 Jun 2020 15:22:35 -0500 Subject: [PATCH 082/239] Experimental change to candidate detection. --- lib/fst240/get_fst240_bitmetrics.f90 | 5 +-- lib/fst240_decode.f90 | 52 +++++++++++++++------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst240/get_fst240_bitmetrics.f90 index ddefbad68..491158264 100644 --- a/lib/fst240/get_fst240_bitmetrics.f90 +++ b/lib/fst240/get_fst240_bitmetrics.f90 @@ -58,6 +58,8 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) is1=0 is2=0 is3=0 + is4=0 + is5=0 badsync=.false. ibmax=0 @@ -74,9 +76,8 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) if(icos8(k-1).eq.(ip(1)-1)) is5=is5+1 enddo nsync=is1+is2+is3+is4+is5 !Number of correct hard sync symbols, 0-40 - badsync=.false. - if(nsync .lt. 8) then + if(nsync .lt. 16) then badsync=.true. return endif diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index c68997bde..9c59492e6 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -131,7 +131,7 @@ contains norder=2 endif - ! The big fft is done once and is used for calculating the smoothed spectrum +! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. r_data(1:nfft1)=iwave(1:nfft1) r_data(nfft1+1:nfft1+2)=0.0 @@ -218,6 +218,7 @@ contains candidates(icand,3)=fc_synced candidates(icand,4)=isbest enddo + ! remove duplicate candidates do icand=1,ncand fc=candidates(icand,3) @@ -226,7 +227,7 @@ contains fc2=candidates(ic2,3) isbest2=nint(candidates(ic2,4)) if(ic2.ne.icand .and. fc2.gt.0.0) then - if(abs(fc2-fc).lt.0.05*baud) then ! same frequency + if(abs(fc2-fc).lt.0.10*baud) then ! same frequency if(abs(isbest2-isbest).le.2) then candidates(ic2,3)=-1 endif @@ -243,6 +244,7 @@ contains endif enddo ncand=ic + do icand=1,ncand sync=candidates(icand,2) fc_synced=candidates(icand,3) @@ -269,7 +271,7 @@ contains ns4=count(hbits(229:244).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 26) cycle !### Value ?? ### + if(nsync_qual.lt. 44) cycle !### Value ?? ### scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) @@ -349,7 +351,7 @@ contains iaptype=0 qual=0. fsig=fc_synced - 1.5*hmod*baud -write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & +write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod) @@ -479,12 +481,14 @@ write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & complex c_bigfft(0:nfft1/2) integer hmod - integer indx(100) + integer indx(100),im(1) real candidates(100,4) real candidates0(100,4) real snr_cand(100) real s(18000) real s2(18000) + real xdb(-3:3) + data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ data nfft1z/-1/ save nfft1z @@ -530,27 +534,25 @@ write(21,'(8i4,f7.1,f7.2,3f7.1,1x,a37)') & candidates=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 - do i=ia,ib - if((s2(i).gt.s2(i-2)).and. & - (s2(i).gt.s2(i+2)).and. & - (s2(i).gt.thresh).and.ncand.lt.100) then - ncand=ncand+1 - candidates(ncand,1)=df2*i - candidates(ncand,2)=s2(i) - endif - enddo - snr_cand=0. - snr_cand(1:ncand)=candidates(1:ncand,2) - call indexx(snr_cand,ncand,indx) - nmax=min(ncand,20) - do i=1,nmax - j=indx(ncand+1-i) - candidates0(i,1:4)=candidates(j,1:4) - enddo - ncand=nmax - candidates(1:ncand,1:4)=candidates0(1:ncand,1:4) - candidates(ncand+1:,1:4)=0. + pval=99.99 + do while(ncand.lt.100 .and. pval.gt.thresh) + im=maxloc(s2(ia:ib)) + iploc=ia+im(1)-1 + pval=s2(iploc) + if(s2(iploc).gt.thresh) then + do i=-3,+3 + k=iploc+2*hmod*i + if(k.ge.ia .and. k.le.ib) then + s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) + endif + enddo + ncand=ncand+1 + candidates(ncand,1)=df2*iploc + candidates(ncand,2)=pval + endif + enddo + return end subroutine get_candidates_fst240 From 5b22280631d7adae582ec76e557a00ff52a43e47 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 28 Jun 2020 16:26:22 -0400 Subject: [PATCH 083/239] Fix the "double-click on AP decode" crash. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 645d7c810..5569385c0 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4501,7 +4501,7 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers) } return; } - DecodedText message {cursor.block().text().trimmed().remove("TU; ")}; + DecodedText message {cursor.block().text().trimmed().left(61).remove("TU; ")}; m_bDoubleClicked = true; processMessage (message, modifiers); } From 494481fa8aa8c8c44d9a6ff761366a1af358feac Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 28 Jun 2020 20:22:24 -0400 Subject: [PATCH 084/239] Remove a poisonous but unused line of code. --- widgets/mainwindow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 71f17093a..6bdd04347 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4575,8 +4575,6 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie int nw=w.size(); if(nw>=4) { if(message_words.size()<3) return; - // Temporary? Correct for the fact that message.deCallAndGrid() does not work for EU VHF contest messages - QString t=message_words.at(nw-2); int n=w.at(nw-2).toInt(); if(n>=520001 and n<=592047) { hiscall=w.at(1); From 5480beba3a6ec48da45cf67d34df9bcf0a590069 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 29 Jun 2020 07:42:00 -0500 Subject: [PATCH 085/239] Change DT search range back to -1s -> 2s. NB - FST240-15 is subject to false sync at DT=+2.5s - bad for EME? --- lib/fst240_decode.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 9c59492e6..c0de49f24 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -165,7 +165,7 @@ contains if(isync.eq.0) then fc1=0.0 is0=1.5*nint(fs2) - ishw=1.5*is0 + ishw=is0 isst=4*hmod ifhw=12 df=.1*baud From 4fbed923aba20555e49f24e8ff56a7e43e5ddb74 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 29 Jun 2020 09:37:29 -0400 Subject: [PATCH 086/239] Add detailed comments to get_candidates_fst240.f90. --- lib/fst240_decode.f90 | 63 ++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 9c59492e6..f52a89880 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -244,6 +244,7 @@ contains endif enddo ncand=ic + xsnr=0. do icand=1,ncand sync=candidates(icand,2) @@ -351,8 +352,8 @@ contains iaptype=0 qual=0. fsig=fc_synced - 1.5*hmod*baud -write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & - nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg +!write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & +! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod) goto 2002 @@ -479,77 +480,79 @@ write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & ncand,candidates,base) - complex c_bigfft(0:nfft1/2) - integer hmod - integer indx(100),im(1) - real candidates(100,4) - real candidates0(100,4) - real snr_cand(100) - real s(18000) - real s2(18000) - real xdb(-3:3) + complex c_bigfft(0:nfft1/2) !Full length FFT of raw data + integer hmod !Modulation index (submode) + integer im(1) !For maxloc + real candidates(100,4) !Candidate list + real s(18000) !Low resolution power spectrum + real s2(18000) !CCF of s() with 4 tones + real xdb(-3:3) !Model 4-tone CCF peaks data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ data nfft1z/-1/ save nfft1z nh1=nfft1/2 df1=fs/nfft1 - baud=fs/nsps + baud=fs/nsps !Keying rate df2=baud/2.0 - nd=df2/df1 + nd=df2/df1 !s() sums this many bins of big FFT ndh=nd/2 - ia=nint(max(100.0,fa)/df2) - ib=nint(min(4800.0,fb)/df2) + ia=nint(max(100.0,fa)/df2) !Low frequency search limit + ib=nint(min(4800.0,fb)/df2) !High frequency limit signal_bw=4*(12000.0/nsps)*hmod analysis_bw=min(4800.0,fb)-max(100.0,fa) - noise_bw=10.0*signal_bw + noise_bw=10.0*signal_bw !Is this a good compromise? if(analysis_bw.gt.noise_bw) then ina=ia inb=ib else - fcenter=(fa+fb)/2.0 - fl = max(100.0,fcenter-noise_bw/2.)/df2 + fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, + fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw fh = min(4800.0,fcenter+noise_bw/2.)/df2 ina=nint(fl) inb=nint(fh) endif - s=0. + + s=0. !Compute low-resloution power spectrum do i=ina,inb ! noise analysis window includes signal analysis window j0=nint(i*df2/df1) do j=j0-ndh,j0+ndh s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 enddo enddo - ina=max(ina,1+3*hmod) + + ina=max(ina,1+3*hmod) !Don't run off the ends inb=min(inb,18000-3*hmod) s2=0. - do i=ina,inb + do i=ina,inb !Compute CCF of s() and 4 tones s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) enddo call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) - s2=s2/base - thresh=1.25 + s2=s2/base !Normalize wrt noise level + thresh=1.25 !First candidate threshold ncand=0 candidates=0 if(ia.lt.3) ia=3 if(ib.gt.18000-2) ib=18000-2 +! Find candidates, using the CLEAN algorithm to remove a model of each one +! from s2() after it has been found. pval=99.99 do while(ncand.lt.100 .and. pval.gt.thresh) im=maxloc(s2(ia:ib)) - iploc=ia+im(1)-1 - pval=s2(iploc) - if(s2(iploc).gt.thresh) then - do i=-3,+3 - k=iploc+2*hmod*i + iploc=ia+im(1)-1 !Index of CCF peak + pval=s2(iploc) !Peak value + if(s2(iploc).gt.thresh) then !Is this a possible candidate? + do i=-3,+3 !Remove 0.9 of a model CCF at + k=iploc+2*hmod*i !this frequency from s2() if(k.ge.ia .and. k.le.ib) then s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) endif enddo ncand=ncand+1 - candidates(ncand,1)=df2*iploc - candidates(ncand,2)=pval + candidates(ncand,1)=df2*iploc !Candidate frequency + candidates(ncand,2)=pval !Rough estimate of SNR endif enddo From 83fddb1f578d134e6fbdcb5da94ab26c7461eb8a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 29 Jun 2020 12:21:34 -0400 Subject: [PATCH 087/239] Pass more parameters to fst240_decode(). --- lib/decoder.f90 | 3 ++- lib/fst240_decode.f90 | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index dee9044de..0266dc2a6 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -193,7 +193,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,params%ndepth,params%ntr,params%nexp_decode, & - params%ntol) + params%ntol,params%nzhsym,params%emedelay, & + logical(params%lapcqonly),params%napwid,mycall,hiscall) call timer('dec240 ',1) go to 800 endif diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index aaf422911..1347654a4 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -27,7 +27,8 @@ module fst240_decode contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & - nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol) + nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol,nzhsym, & + emedelay,lapcqonly,napwid,mycall,hiscall) use timer_module, only: timer use packjt77 @@ -38,6 +39,7 @@ contains character*37 decodes(100) character*37 msg character*77 c77 + character*12 mycall,hiscall complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform @@ -46,6 +48,7 @@ contains real candidates(100,4) real bitmetrics(320,4) real s4(0:3,NN) + logical lapcqonly integer itone(NN) integer hmod integer*1 apmask(240),cw(240) @@ -58,6 +61,9 @@ contains 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/ + write(*,3001) nzhsym,emedelay,lapcqonly,napwid,mycall,hiscall +3001 format(i4,f6.1,L3,i3,2x,2a12) + this%callback => callback hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return From 06b8e0eec6c848a50088ce1aee206fcb3bdebc7b Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 29 Jun 2020 12:15:28 -0500 Subject: [PATCH 088/239] Try to ensure that nfft1 and nfft2 are nice values. Add a brickwall filter in the downsampler. --- lib/fst240_decode.f90 | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 1347654a4..a0ad0591e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -76,26 +76,38 @@ contains nmax=15*12000 ndown=20/hmod !nss=40,80,160,400 if(hmod.eq.8) ndown=2 + nfft1=int(nmax/ndown)*ndown else if(ntrperiod.eq.30) then nsps=1680 nmax=30*12000 ndown=42/hmod !nss=40,80,168,336 - if(hmod.eq.4) ndown=10 - if(hmod.eq.8) ndown=5 + nfft1=359856 + if(hmod.eq.4) then + ndown=10 + nfft1=nmax + endif + if(hmod.eq.8) then + ndown=5 + nfft1=nmax + endif + nfft1=int(nmax/ndown)*ndown else if(ntrperiod.eq.60) then nsps=3888 nmax=60*12000 ndown=96/hmod !nss=36,81,162,324 if(hmod.eq.1) ndown=108 + nfft1=int(719808/ndown)*ndown else if(ntrperiod.eq.120) then nsps=8200 nmax=120*12000 ndown=200/hmod !nss=40,82,164,328 if(hmod.eq.1) ndown=205 + nfft1=int(nmax/ndown)*ndown else if(ntrperiod.eq.300) then nsps=21504 nmax=300*12000 ndown=512/hmod !nss=42,84,168,336 + nfft1=int((nmax-200)/ndown)*ndown end if nss=nsps/ndown fs=12000.0 !Sample rate @@ -105,16 +117,17 @@ contains dt2=1.0/fs2 tt=nsps*dt !Duration of "itone" symbols (s) baud=1.0/tt - nfft1=2*int(nmax/2) - nh1=nfft1/2 + sigbw=4.0*hmod*baud + nfft2=nfft1/ndown !make sure that nfft1 is exactly nfft2*ndown + nfft1=nfft2*ndown + nh1=nfft1/2 + allocate( r_data(1:nfft1+2) ) allocate( c_bigfft(0:nfft1/2) ) - nfft2=nfft1/ndown allocate( c2(0:nfft2-1) ) - allocate( cframe(0:164*nss-1) ) + allocate( cframe(0:160*nss-1) ) - npts=nmax if(single_decode) then fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) @@ -164,7 +177,7 @@ contains ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown - call fst240_downsample(c_bigfft,nfft1,ndown,fc0,c2) + call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) call timer('sync240 ',0) do isync=0,1 @@ -257,7 +270,7 @@ contains fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 - call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,c2) + call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) do ijitter=0,jittermax if(ijitter.eq.0) ioffset=0 @@ -462,7 +475,7 @@ contains return end subroutine sync_fst240 - subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,c1) + subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) ! Output: Complex data in c(), sampled at 12000/ndown Hz @@ -471,9 +484,12 @@ contains df=12000.0/nfft1 i0=nint(f0/df) + ih=nint( ( f0 + 1.2*sigbw/2.0 )/df) + nbw=ih-i0+1 + c1=0. c1(0)=c_bigfft(i0) nfft2=nfft1/ndown - do i=1,nfft2/2 + do i=1,nbw if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) enddo From 67422f2ede74a7d5b2ef622a4b5c820e01dc298e Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 29 Jun 2020 13:28:06 -0400 Subject: [PATCH 089/239] Remove a diagnostic write statement. --- lib/fst240_decode.f90 | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 1347654a4..106344139 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -61,9 +61,6 @@ contains 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/ - write(*,3001) nzhsym,emedelay,lapcqonly,napwid,mycall,hiscall -3001 format(i4,f6.1,L3,i3,2x,2a12) - this%callback => callback hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return From a5cb88deed4aa2c8780934ac1a9aad3079ba9e89 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 29 Jun 2020 12:31:16 -0500 Subject: [PATCH 090/239] Use two alternating sync words. Change DT=0 to t=0.5 s for ntrperiod=15 s only. --- lib/fst240/genfst240.f90 | 15 ++++++++------- lib/fst240/get_fst240_bitmetrics.f90 | 15 ++++++++------- lib/fst240_decode.f90 | 5 +++-- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/fst240/genfst240.f90 b/lib/fst240/genfst240.f90 index b442b3efa..f60dc8446 100644 --- a/lib/fst240/genfst240.f90 +++ b/lib/fst240/genfst240.f90 @@ -20,10 +20,11 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) integer*4 i4tone(NN),itmp(ND) integer*1 codeword(2*ND) integer*1 msgbits(101),rvec(77) - integer isyncword(8) + integer isyncword1(8),isyncword2(8) integer ncrc24 logical unpk77_success - data isyncword/0,1,3,2,1,0,2,3/ + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & 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/ @@ -86,15 +87,15 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) if(is.eq.3) itmp(i)=2 enddo - i4tone( 1: 8)=isyncword + i4tone( 1: 8)=isyncword1 i4tone( 9: 38)=itmp( 1: 30) - i4tone( 39: 46)=isyncword + i4tone( 39: 46)=isyncword2 i4tone( 47: 76)=itmp( 31: 60) - i4tone( 77: 84)=isyncword + i4tone( 77: 84)=isyncword1 i4tone( 85:114)=itmp( 61: 90) - i4tone(115:122)=isyncword + i4tone(115:122)=isyncword2 i4tone(123:152)=itmp( 91:120) - i4tone(153:160)=isyncword + i4tone(153:160)=isyncword1 999 return diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst240/get_fst240_bitmetrics.f90 index 491158264..60804cba7 100644 --- a/lib/fst240/get_fst240_bitmetrics.f90 +++ b/lib/fst240/get_fst240_bitmetrics.f90 @@ -7,7 +7,7 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) complex, allocatable, save :: c1(:,:) ! ideal waveforms, 20 samples per symbol, 4 tones complex cp(0:3) ! accumulated phase shift over symbol types 0:3 complex csum,cterm - integer icos8(0:7) + integer isyncword1(0:7),isyncword2(0:7) integer graymap(0:3) integer ip(1) integer hmod @@ -17,7 +17,8 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) real bitmetrics(2*NN,4) real s2(0:65535) real s4(0:3,NN) - data icos8/0,1,3,2,1,0,2,3/ + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ data graymap/0,1,3,2/ data first/.true./,nss0/-1/ save first,one,cp,nss0 @@ -65,15 +66,15 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) do k=1,8 ip=maxloc(s4(:,k)) - if(icos8(k-1).eq.(ip(1)-1)) is1=is1+1 + if(isyncword1(k-1).eq.(ip(1)-1)) is1=is1+1 ip=maxloc(s4(:,k+38)) - if(icos8(k-1).eq.(ip(1)-1)) is2=is2+1 + if(isyncword2(k-1).eq.(ip(1)-1)) is2=is2+1 ip=maxloc(s4(:,k+76)) - if(icos8(k-1).eq.(ip(1)-1)) is3=is3+1 + if(isyncword1(k-1).eq.(ip(1)-1)) is3=is3+1 ip=maxloc(s4(:,k+114)) - if(icos8(k-1).eq.(ip(1)-1)) is4=is4+1 + if(isyncword2(k-1).eq.(ip(1)-1)) is4=is4+1 ip=maxloc(s4(:,k+152)) - if(icos8(k-1).eq.(ip(1)-1)) is5=is5+1 + if(isyncword1(k-1).eq.(ip(1)-1)) is5=is5+1 enddo nsync=is1+is2+is3+is4+is5 !Number of correct hard sync symbols, 0-40 badsync=.false. diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index a0ad0591e..4fded52ae 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -270,6 +270,7 @@ contains fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 + if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) do ijitter=0,jittermax @@ -286,9 +287,9 @@ contains hbits=0 where(bitmetrics(:,1).ge.0) hbits=1 ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns2=count(hbits( 77: 92).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns4=count(hbits(229:244).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 if(nsync_qual.lt. 44) cycle !### Value ?? ### From ae6ca148bd46f0e51995756e7ae6ba20cb498a0e Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 29 Jun 2020 14:47:46 -0400 Subject: [PATCH 091/239] Pass mode name to the Modulator. --- Modulator/Modulator.cpp | 6 +++--- Modulator/Modulator.hpp | 2 +- widgets/mainwindow.cpp | 30 ++++++++++++------------------ widgets/mainwindow.h | 4 ++-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index f267022e0..7b06cd915 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -45,7 +45,7 @@ Modulator::Modulator (unsigned frameRate, double periodLengthInSeconds, { } -void Modulator::start (unsigned symbolsLength, double framesPerSymbol, +void Modulator::start (QString mode, unsigned symbolsLength, double framesPerSymbol, double frequency, double toneSpacing, SoundOutput * stream, Channel channel, bool synchronize, bool fastMode, double dBSNR, double TRperiod) @@ -69,8 +69,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, m_bFastMode=fastMode; m_TRperiod=TRperiod; unsigned delay_ms=1000; - if(m_nsps==1920) delay_ms=500; //FT8 - if(m_nsps==576) delay_ms=300; //FT4 + if(mode=="FT8" or (mode=="FST240" and m_nsps==800)) delay_ms=500; //FT8, FST240-15 + if(mode=="FT4") delay_ms=300; //FT4 // noise generator parameters if (m_addNoise) { diff --git a/Modulator/Modulator.hpp b/Modulator/Modulator.hpp index 1043be697..c25074efe 100644 --- a/Modulator/Modulator.hpp +++ b/Modulator/Modulator.hpp @@ -35,7 +35,7 @@ public: void set_nsym(int n) {m_symbolsLength=n;} void set_ms0(qint64 ms) {m_ms0=ms;} - Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, double frequency, + Q_SLOT void start (QString mode, unsigned symbolsLength, double framesPerSymbol, double frequency, double toneSpacing, SoundOutput *, Channel = Mono, bool synchronize = true, bool fastMode = false, double dBSNR = 99., double TRperiod=60.0); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6bdd04347..097cec75a 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -7133,7 +7133,7 @@ void MainWindow::transmit (double snr) if(m_nSubMode==0) toneSpacing=11025.0/4096.0; if(m_nSubMode==1) toneSpacing=2*11025.0/4096.0; if(m_nSubMode==2) toneSpacing=4*11025.0/4096.0; - Q_EMIT sendMessage (NUM_JT65_SYMBOLS, + Q_EMIT sendMessage (m_mode, NUM_JT65_SYMBOLS, 4096.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, false, snr, m_TRperiod); @@ -7145,7 +7145,7 @@ void MainWindow::transmit (double snr) 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; - Q_EMIT sendMessage (NUM_FT8_SYMBOLS, + Q_EMIT sendMessage (m_mode, NUM_FT8_SYMBOLS, 1920.0, ui->TxFreqSpinBox->value () - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, false, snr, m_TRperiod); @@ -7154,7 +7154,7 @@ void MainWindow::transmit (double snr) if (m_modeTx == "FT4") { m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. - Q_EMIT sendMessage (NUM_FT4_SYMBOLS, + Q_EMIT sendMessage (m_mode, NUM_FT4_SYMBOLS, 576.0, ui->TxFreqSpinBox->value() - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel(), true, false, snr, m_TRperiod); @@ -7171,7 +7171,7 @@ void MainWindow::transmit (double snr) int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; - Q_EMIT sendMessage (NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, + Q_EMIT sendMessage (m_mode, NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); } @@ -7182,7 +7182,7 @@ void MainWindow::transmit (double snr) if(m_nSubMode==2) toneSpacing=4*12000.0/6912.0; if(m_nSubMode==3) toneSpacing=8*12000.0/6912.0; if(m_nSubMode==4) toneSpacing=16*12000.0/6912.0; - Q_EMIT sendMessage (NUM_QRA64_SYMBOLS, + Q_EMIT sendMessage (m_mode, NUM_QRA64_SYMBOLS, 6912.0, ui->TxFreqSpinBox->value () - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, false, snr, m_TRperiod); @@ -7201,7 +7201,7 @@ void MainWindow::transmit (double snr) sps=nsps[m_nSubMode-4]; m_toneSpacing=12000.0/sps; } - Q_EMIT sendMessage (NUM_JT9_SYMBOLS, sps, + Q_EMIT sendMessage (m_mode, NUM_JT9_SYMBOLS, sps, ui->TxFreqSpinBox->value() - m_XIT, m_toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, fastmode, snr, m_TRperiod); @@ -7220,7 +7220,7 @@ void MainWindow::transmit (double snr) int nsym; nsym=NUM_MSK144_SYMBOLS; if(itone[40] < 0) nsym=40; - Q_EMIT sendMessage (nsym, double(m_nsps), f0, m_toneSpacing, + Q_EMIT sendMessage (m_mode, nsym, double(m_nsps), f0, m_toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, true, snr, m_TRperiod); } @@ -7233,7 +7233,7 @@ void MainWindow::transmit (double snr) if(m_nSubMode==4) toneSpacing=18*4.375; if(m_nSubMode==5) toneSpacing=36*4.375; if(m_nSubMode==6) toneSpacing=72*4.375; - Q_EMIT sendMessage (NUM_JT4_SYMBOLS, + Q_EMIT sendMessage (m_mode, NUM_JT4_SYMBOLS, 2520.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel (), true, false, snr, m_TRperiod); @@ -7242,22 +7242,16 @@ void MainWindow::transmit (double snr) int nToneSpacing=1; if(m_config.x2ToneSpacing()) nToneSpacing=2; if(m_config.x4ToneSpacing()) nToneSpacing=4; - Q_EMIT sendMessage (NUM_WSPR_SYMBOLS, 8192.0, + Q_EMIT sendMessage (m_mode, NUM_WSPR_SYMBOLS, 8192.0, ui->TxFreqSpinBox->value() - 1.5 * 12000 / 8192, m_toneSpacing*nToneSpacing, m_soundOutput, m_config.audio_output_channel(),true, false, snr, m_TRperiod); } - if (m_mode=="WSPR-LF") { - Q_EMIT sendMessage (NUM_WSPR_LF_SYMBOLS, 24576.0, - ui->TxFreqSpinBox->value(), - m_toneSpacing, m_soundOutput, - m_config.audio_output_channel(),true, false, snr, - m_TRperiod); - } + if(m_mode=="Echo") { //??? should use "fastMode = true" here ??? - Q_EMIT sendMessage (27, 1024.0, 1500.0, 0.0, m_soundOutput, + Q_EMIT sendMessage (m_mode, 27, 1024.0, 1500.0, 0.0, m_soundOutput, m_config.audio_output_channel(), false, false, snr, m_TRperiod); } @@ -7273,7 +7267,7 @@ void MainWindow::transmit (double snr) toneSpacing=11025.0/256.0; f0=13*toneSpacing; } - Q_EMIT sendMessage (NUM_ISCAT_SYMBOLS, sps, f0, toneSpacing, m_soundOutput, + Q_EMIT sendMessage (m_mode, NUM_ISCAT_SYMBOLS, sps, f0, toneSpacing, m_soundOutput, m_config.audio_output_channel(), true, true, snr, m_TRperiod); } diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index e62f7da9a..001742f7f 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -337,8 +337,8 @@ private: 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, + Q_SIGNAL void sendMessage (QString mode, 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; From 355b060454ce4edd1a935846b9517a423e90828b Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 29 Jun 2020 15:06:11 -0500 Subject: [PATCH 092/239] 1. Fix broken sync. 2. Change FST240-15 to use nsps=720 --- lib/fst240/fst240sim.f90 | 5 ++-- lib/fst240/gen_fst240wave.f90 | 12 ++++----- lib/fst240_decode.f90 | 50 ++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index 9cca82504..ceefa00e8 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -47,7 +47,7 @@ program fst240sim fs=12000.0 !Sample rate (Hz) dt=1.0/fs !Sample interval (s) nsps=0 - if(nsec.eq.15) nsps=800 + if(nsec.eq.15) nsps=720 if(nsec.eq.30) nsps=1680 if(nsec.eq.60) nsps=3888 if(nsec.eq.120) nsps=8200 @@ -99,7 +99,8 @@ program fst240sim icmplx=1 f0=f00+1.5*hmod*baud call gen_fst240wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) - k=nint(xdt/dt) + k=nint((xdt+1.0)/dt) + if(nsec.eq.15) k=nint((xdt+0.5)/dt) c0=cshift(c0,-k) if(k.gt.0) c0(0:k-1)=0.0 if(k.lt.0) c0(nmax+k:nmax-1)=0.0 diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst240/gen_fst240wave.f90 index 43170638d..3ba1c2d82 100644 --- a/lib/fst240/gen_fst240wave.f90 +++ b/lib/fst240/gen_fst240wave.f90 @@ -71,19 +71,19 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & wave(1:nsps)=0.0 wave(nsps+1:nsps+nsps/4)=wave(nsps+1:nsps+nsps/4) * & (1.0-cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 - k1=nsym*nsps+3*nsps/4 + k1=nsym*nsps+3*nsps/4+1 wave((nsym+1)*nsps+1:)=0.0 - wave(k1:k1+nsps/4-1)=wave(k1:k1+nsps/4-1) * & - (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + wave(k1:k1+nsps/4)=wave(k1:k1+nsps/4) * & + (1.0+cos(twopi*(/(i,i=0,nsps/4)/)/real(nsps/2)))/2.0 wave=cshift(wave,kshift) else cwave(1:nsps)=0.0 cwave(nsps+1:nsps+nsps/4)=cwave(nsps+1:nsps+nsps/4) * & (1.0-cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 - k1=nsym*nsps+3*nsps/4 + k1=nsym*nsps+3*nsps/4+1 cwave((nsym+1)*nsps+1:)=0.0 - cwave(k1:k1+nsps/4-1)=cwave(k1:k1+nsps/4-1) * & - (1.0+cos(twopi*(/(i,i=0,nsps/4-1)/)/real(nsps/2)))/2.0 + cwave(k1:k1+nsps/4)=cwave(k1:k1+nsps/4) * & + (1.0+cos(twopi*(/(i,i=0,nsps/4)/)/real(nsps/2)))/2.0 cwave=cshift(cwave,kshift) endif diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 2465065fd..46a047b53 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -69,9 +69,10 @@ contains nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then - nsps=800 + nsps=720 nmax=15*12000 - ndown=20/hmod !nss=40,80,160,400 + ndown=18/hmod !nss=40,80,160,400 + if(hmod.eq.4) ndown=4 if(hmod.eq.8) ndown=2 nfft1=int(nmax/ndown)*ndown else if(ntrperiod.eq.30) then @@ -87,7 +88,6 @@ contains ndown=5 nfft1=nmax endif - nfft1=int(nmax/ndown)*ndown else if(ntrperiod.eq.60) then nsps=3888 nmax=60*12000 @@ -276,7 +276,7 @@ contains if(ijitter.eq.2) ioffset=-1 is0=isbest+ioffset if(is0.lt.0) cycle - cframe=c2(is0:is0+164*nss-1) + cframe=c2(is0:is0+160*nss-1) bitmetrics=0 call get_fst240_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,s4,badsync) if(badsync) cycle @@ -392,31 +392,36 @@ contains include 'fst240/fst240_params.f90' complex cd0(0:np-1) - complex, allocatable, save :: csync(:) - complex, allocatable, save :: csynct(:) + complex, allocatable, save :: csync1(:),csync2(:) + complex, allocatable, save :: csynct1(:),csynct2(:) complex ctwk(8*nss) complex z1,z2,z3,z4,z5 logical first - integer hmod,isyncword(0:7) + integer hmod,isyncword1(0:7),isyncword2(0:7) real f0save - data isyncword/0,1,3,2,1,0,2,3/ + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ data first/.true./,f0save/-99.9/,nss0/-1/ save first,twopi,dt,fac,f0save,nss0 p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power - if(nss.ne.nss0 .and. allocated(csync)) deallocate(csync,csynct) + if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) if(first .or. nss.ne.nss0) then - allocate( csync(8*nss) ) - allocate( csynct(8*nss) ) + allocate( csync1(8*nss), csync2(8*nss) ) + allocate( csynct1(8*nss), csynct2(8*nss) ) twopi=8.0*atan(1.0) dt=1/fs k=1 - phi=0.0 + phi1=0.0 + phi2=0.0 do i=0,7 - dphi=twopi*hmod*(isyncword(i)-1.5)/real(nss) + dphi1=twopi*hmod*(isyncword1(i)-1.5)/real(nss) + dphi2=twopi*hmod*(isyncword2(i)-1.5)/real(nss) do j=1,nss - csync(k)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dphi,twopi) + csync1(k)=cmplx(cos(phi1),sin(phi1)) + csync2(k)=cmplx(cos(phi2),sin(phi2)) + phi1=mod(phi1+dphi1,twopi) + phi2=mod(phi2+dphi2,twopi) k=k+1 enddo enddo @@ -432,7 +437,8 @@ contains ctwk(i)=cmplx(cos(phi),sin(phi)) phi=mod(phi+dphi,twopi) enddo - csynct=ctwk*csync + csynct1=ctwk*csync1 + csynct2=ctwk*csync2 f0save=f0 endif @@ -453,14 +459,14 @@ contains is=(i-1)*ncoh*nss z1=0 if(i1+is.ge.1) then - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) endif - z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) - z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) z5=0 if(i5+is+ncoh*nss-1.le.np) then - z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct(is+1:is+ncoh*nss))) + z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) endif s1=s1+abs(z1)/(8*nss) s2=s2+abs(z2)/(8*nss) @@ -482,7 +488,7 @@ contains df=12000.0/nfft1 i0=nint(f0/df) - ih=nint( ( f0 + 1.2*sigbw/2.0 )/df) + ih=nint( ( f0 + 1.3*sigbw/2.0 )/df) nbw=ih-i0+1 c1=0. c1(0)=c_bigfft(i0) From d462277a3ed3e46d3a6e8912ad7e9d8e807e50ba Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 29 Jun 2020 16:09:12 -0500 Subject: [PATCH 093/239] Make ldpcsim program work again. --- lib/fst240/ldpcsim240_101.f90 | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/fst240/ldpcsim240_101.f90 b/lib/fst240/ldpcsim240_101.f90 index 55121b5c3..e201ac413 100644 --- a/lib/fst240/ldpcsim240_101.f90 +++ b/lib/fst240/ldpcsim240_101.f90 @@ -32,7 +32,7 @@ program ldpcsim240_101 call getarg(1,arg) read(arg,*) max_iterations call getarg(2,arg) - read(arg,*) ndeep + read(arg,*) norder call getarg(3,arg) read(arg,*) ntrials call getarg(4,arg) @@ -47,7 +47,7 @@ program ldpcsim240_101 write(*,*) "code rate: ",rate write(*,*) "niter : ",max_iterations - write(*,*) "ndeep : ",ndeep + write(*,*) "norder : ",norder write(*,*) "s : ",s write(*,*) "K : ",Keff @@ -100,19 +100,13 @@ write(*,'(24i1)') msgbits(78:101) llr=2.0*rxdata/(ss*ss) apmask=0 -! max_iterations is max number of belief propagation iterations - call bpdecode240_101(llr,apmask,max_iterations,message101,cw,nharderror,niterations,nchecks) dmin=0.0 - if( (nharderror .lt. 0) .and. (ndeep .ge. 0) ) then -! call osd240_101(llr, Keff, apmask, ndeep, message101, cw, nharderror, dmin) - maxsuper=2 - call decode240_101(llr, Keff, ndeep, apmask, maxsuper, message101, cw, nharderror, iterations, ncheck, dmin, isuper) - endif - + maxosd=2 + call decode240_101(llr, Keff, maxosd, norder, apmask, message101, cw, ntype, nharderror, dmin) if(nharderror.ge.0) then n2err=0 do i=1,N - if( cw(i)*(2*codeword(i)-1.0) .lt. 0 ) n2err=n2err+1 + if( cw(i).ne.codeword(i) ) n2err=n2err+1 enddo if(n2err.eq.0) then ngood=ngood+1 From a44b240192323e4ee677d430014984556cdcd900 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 29 Jun 2020 17:33:46 -0400 Subject: [PATCH 094/239] Change to NSPS=720 for 15-seconf FST240 modes, to allow use for EME. --- Modulator/Modulator.cpp | 2 +- widgets/mainwindow.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index 7b06cd915..8308a44cb 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -69,7 +69,7 @@ void Modulator::start (QString mode, unsigned symbolsLength, double framesPerSym m_bFastMode=fastMode; m_TRperiod=TRperiod; unsigned delay_ms=1000; - if(mode=="FT8" or (mode=="FST240" and m_nsps==800)) delay_ms=500; //FT8, FST240-15 + if(mode=="FT8" or (mode=="FST240" and m_nsps==720)) delay_ms=500; //FT8, FST240-15 if(mode=="FT4") delay_ms=300; //FT4 // noise generator parameters diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 097cec75a..1ff8edaac 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1342,8 +1342,8 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST240" or m_mode=="FST240W") { - int stop[] = {44,85,187,387,1003}; - int stop_EME[] = {51,95,197,396,1012}; + int stop[] = {39,85,187,387,1003}; + int stop_EME[] = {48,95,197,396,1012}; int i=0; if(m_TRperiod==30) i=1; if(m_TRperiod==60) i=2; @@ -3538,7 +3538,7 @@ void MainWindow::guiUpdate() if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR if(m_modeTx=="FST240" or m_mode=="FST240W") { //FST240, FST240W - if(m_TRperiod==15) txDuration=1.0 + 160*800/12000.0; + if(m_TRperiod==15) txDuration=1.0 + 160*720/12000.0; if(m_TRperiod==30) txDuration=1.0 + 160*1680/12000.0; if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0; @@ -3882,7 +3882,7 @@ void MainWindow::guiUpdate() genfst240_(message,&ichk,msgsent,const_cast (fst240msgbits), const_cast(itone), &iwspr, 37, 37); int hmod=int(pow(2.0,double(m_nSubMode))); - int nsps=800; + int nsps=720; if(m_TRperiod==30) nsps=1680; if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; @@ -7163,7 +7163,7 @@ void MainWindow::transmit (double snr) if (m_modeTx == "FST240" or m_modeTx == "FST240W") { m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. - int nsps=800; + int nsps=720; if(m_TRperiod==30) nsps=1680; if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; From 023e09bc4d2533288872a2a9d8af9b9f465bf3d6 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 30 Jun 2020 08:58:40 -0400 Subject: [PATCH 095/239] Correct the help message's option label for setting FST240 mode. --- lib/jt9.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 23f330c9f..1bebf56f9 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -54,7 +54,7 @@ program jt9 option ('jt4', .false., '4', 'JT4 mode', ''), & option ('ft4', .false., '5', 'FT4 mode', ''), & option ('jt65', .false.,'6', 'JT65 mode', ''), & - option ('fst240', .false., '7', 'FT8 mode', ''), & + option ('fst240', .false., '7', 'FST240 mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & From d34f05f985e2b4d125be82274e99718fb918a80a Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 08:42:54 -0500 Subject: [PATCH 096/239] Implement basic AP decoding for FST240. No contests. --- lib/fst240_decode.f90 | 152 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 9 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 46a047b53..5c5d07838 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -37,9 +37,10 @@ contains class(fst240_decoder), intent(inout) :: this procedure(fst240_decode_callback) :: callback character*37 decodes(100) - character*37 msg + character*37 msg,msgsent character*77 c77 character*12 mycall,hiscall + character*12 mycall0,hiscall0 complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform @@ -53,15 +54,103 @@ contains integer hmod integer*1 apmask(240),cw(240) integer*1 hbits(320) - integer*1 message101(101),message74(74) + integer*1 message101(101),message74(74),message77(77) integer*1 rvec(77) + integer apbits(240) + integer nappasses(0:5) ! # of decoding passes for QSO states 0-5 + integer naptypes(0:5,4) ! (nQSOProgress,decoding pass) + integer mcq(29),mrrr(19),m73(19),mrr73(19) + logical badsync,unpk77_success,single_decode + logical first,nohiscall + integer*2 iwave(300*12000) - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 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/ + + data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ + data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ + data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ + data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ + data first/.true./ + save first,apbits,nappasses,naptypes,mycall0,hiscall0 this%callback => callback + + dxcall13=hiscall ! initialize for use in packjt77 + mycall13=mycall + + if(first) then + mcq=2*mod(mcq+rvec(1:29),2)-1 + 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 + + nappasses(0)=2 + nappasses(1)=2 + nappasses(2)=2 + nappasses(3)=2 + nappasses(4)=2 + nappasses(5)=3 + +! iaptype +!------------------------ +! 1 CQ ??? ??? (29 ap bits) +! 2 MyCall ??? ??? (29 ap bits) +! 3 MyCall DxCall ??? (58 ap bits) +! 4 MyCall DxCall RRR (77 ap bits) +! 5 MyCall DxCall 73 (77 ap bits) +! 6 MyCall DxCall RR73 (77 ap bits) +!******** + + naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) + naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 + naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 + naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 + naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 + naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 + + mycall0='' + hiscall0='' + first=.false. + endif + + l1=index(mycall,char(0)) + if(l1.ne.0) mycall(l1:)=" " + l1=index(hiscall,char(0)) + if(l1.ne.0) hiscall(l1:)=" " + if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then + apbits=0 + apbits(1)=99 + apbits(30)=99 + + if(len(trim(mycall)) .lt. 3) go to 10 + + nohiscall=.false. + hiscall0=hiscall + if(len(trim(hiscall0)).lt.3) then + hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. + nohiscall=.true. + endif + msg=trim(mycall)//' '//trim(hiscall0)//' RR73' + i3=-1 + n3=-1 + call pack77(msg,i3,n3,c77) + call unpack77(c77,1,msgsent,unpk77_success) + if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 + read(c77,'(77i1)') message77 + message77=mod(message77+rvec,2) + call encode174_91(message77,cw) + apbits=2*cw-1 + if(nohiscall) apbits(30)=99 + +10 continue + mycall0=mycall + hiscall0=hiscall + endif +!************************************ + hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return Keff=91 @@ -278,7 +367,7 @@ contains if(is0.lt.0) cycle cframe=c2(is0:is0+160*nss-1) bitmetrics=0 - call get_fst240_bitmetrics(cframe,nss,hmod,ntmax,bitmetrics,s4,badsync) + call get_fst240_bitmetrics(cframe,nss,hmod,4,bitmetrics,s4,badsync) if(badsync) cycle hbits=0 @@ -312,6 +401,11 @@ contains llrd(121:180)=bitmetrics(169:228, 4) llrd(181:240)=bitmetrics(245:304, 4) llrd=scalefac*llrd + + apmag=maxval(abs(llra))*1.1 + ntmax=4+nappasses(nQSOProgress) + if(lapcqonly) ntmax=5 + if(ndepth.eq.1) ntmax=3 apmask=0 do itry=1,ntmax @@ -319,6 +413,47 @@ contains if(itry.eq.2) llr=llrb if(itry.eq.3) llr=llrc if(itry.eq.4) llr=llrd + if(itry.le.4) then + apmask=0 + iaptype=0 + endif + napwid=1.2*(4.0*baud*hmod) + + if(itry.gt.4) then + llr=llra + iaptype=naptypes(nQSOProgress,itry-4) + if(lapcqonly) iaptype=1 + if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall + if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall + + if(iaptype.eq.1) then ! CQ + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*mcq(1:29) + endif + + if(iaptype.eq.2) then ! MyCall ??? ??? + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*apbits(1:29) + endif + + if(iaptype.eq.3) then ! MyCall DxCall ??? + apmask=0 + apmask(1:58)=1 + llr(1:58)=apmag*apbits(1:58) + endif + + if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then + apmask=0 + apmask(1:77)=1 + llr(1:58)=apmag*apbits(1:58) + if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) + if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) + if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) + endif + endif + dmin=0.0 nharderrors=-1 unpk77_success=.false. @@ -366,11 +501,10 @@ contains endif endif nsnr=nint(xsnr) - iaptype=0 qual=0. fsig=fc_synced - 1.5*hmod*baud -!write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & -! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg +write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & + nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod) goto 2002 From 2a74e5a5de38f95e431cdfbedcea496378df1d76 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 30 Jun 2020 10:35:13 -0400 Subject: [PATCH 097/239] Allow command-line argument for "nQSOProgress" in jt9. --- lib/jt9.f90 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 1bebf56f9..679c2ef22 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -23,10 +23,10 @@ program jt9 character wisfile*80 !### ndepth was defined as 60001. Why??? integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, & - fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0 + fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0,nQSOProg=0 logical :: read_files = .true., tx9 = .false., display_help = .false., & bLowSidelobes = .false. - type (option) :: long_options(27) = [ & + type (option) :: long_options(28) = [ & option ('help', .false., 'h', 'Display this help message', ''), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', & @@ -58,9 +58,11 @@ program jt9 option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & + option ('QSOprog', .true., 'Q', 'QSO progress (0-5), default PROGRESS=1',& + 'QSOprogress'), & option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), & option ('depth', .true., 'd', & - 'JT9 decoding depth (1-3), default DEPTH=1', 'DEPTH'), & + 'Decoding depth (1-3), default DEPTH=1', 'DEPTH'), & option ('tx-jt9', .false., 'T', 'Tx mode is JT9', ''), & option ('my-call', .true., 'c', 'my callsign', 'CALL'), & option ('my-grid', .true., 'G', 'my grid locator', 'GRID'), & @@ -82,7 +84,7 @@ program jt9 TRperiod=60.d0 do - call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654qTL:S:H:c:G:x:g:X:', & + call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654qTL:S:H:c:G:x:g:X:Q:', & long_options,c,optarg,arglen,stat,offset,remain,.true.) if (stat .ne. 0) then exit @@ -117,6 +119,8 @@ program jt9 read (optarg(:arglen), *) fhigh case ('q') mode = 164 + case ('Q') + read (optarg(:arglen), *) nQSOProg case ('4') mode = 4 case ('5') @@ -260,7 +264,7 @@ program jt9 if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100 shared_data%params%naggressive=0 shared_data%params%n2pass=2 -! shared_data%params%nranera=8 !### ntrials=10000 + shared_data%params%nQSOprogress=nQSOProg shared_data%params%nranera=6 !### ntrials=3000 shared_data%params%nrobust=.false. shared_data%params%nexp_decode=nexp_decode From d916f315d363146bdb4a83a5eb815bd72012e3e6 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 11:39:51 -0500 Subject: [PATCH 098/239] Make AP decoding baseline llrs depend on hmod. Center the DT search window on emedelay. --- lib/fst240_decode.f90 | 49 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 5c5d07838..85038769f 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -223,17 +223,19 @@ contains endif if(ndeep.eq.3) then - ntmax=4 ! number of block sizes to try + nblock=1 + if(hmod.eq.1) nblock=4 ! number of block sizes to try jittermax=2 norder=3 elseif(ndeep.eq.2) then - ntmax=3 - jittermax=2 + nblock=1 + if(hmod.eq.1) nblock=3 + jittermax=0 norder=3 elseif(ndeep.eq.1) then - ntmax=1 - jittermax=2 - norder=2 + nblock=1 + jittermax=0 + norder=3 endif ! The big fft is done once and is used for calculating the smoothed spectrum @@ -269,8 +271,13 @@ contains do isync=0,1 if(isync.eq.0) then fc1=0.0 - is0=1.5*nint(fs2) - ishw=is0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint(emedelay*nspsec) + ishw=1.5*nspsec + endif isst=4*hmod ifhw=12 df=.1*baud @@ -310,12 +317,10 @@ contains if(smax8/smax1 .lt. 0.65 ) then fc2=fc21 isbest=isbest1 - if(hmod.gt.1) ntmax=1 njitter=2 else fc2=fc28 isbest=isbest8 - if(hmod.gt.1) ntmax=1 njitter=2 endif fc_synced = fc0 + fc2 @@ -367,7 +372,7 @@ contains if(is0.lt.0) cycle cframe=c2(is0:is0+160*nss-1) bitmetrics=0 - call get_fst240_bitmetrics(cframe,nss,hmod,4,bitmetrics,s4,badsync) + call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) if(badsync) cycle hbits=0 @@ -403,29 +408,29 @@ contains llrd=scalefac*llrd apmag=maxval(abs(llra))*1.1 - ntmax=4+nappasses(nQSOProgress) - if(lapcqonly) ntmax=5 - if(ndepth.eq.1) ntmax=3 + ntmax=nblock+nappasses(nQSOProgress) + if(lapcqonly) ntmax=nblock+1 + if(ndepth.eq.1) ntmax=nblock apmask=0 do itry=1,ntmax if(itry.eq.1) llr=llra - if(itry.eq.2) llr=llrb - if(itry.eq.3) llr=llrc - if(itry.eq.4) llr=llrd - if(itry.le.4) then + if(itry.eq.2.and.itry.le.nblock) llr=llrb + if(itry.eq.3.and.itry.le.nblock) llr=llrc + if(itry.eq.4.and.itry.le.nblock) llr=llrd + if(itry.le.nblock) then apmask=0 iaptype=0 endif napwid=1.2*(4.0*baud*hmod) - if(itry.gt.4) then - llr=llra - iaptype=naptypes(nQSOProgress,itry-4) + if(itry.gt.nblock) then + if(nblock.eq.1) llr=llra + if(nblock.gt.1) llr=llrc + iaptype=naptypes(nQSOProgress,itry-nblock) if(lapcqonly) iaptype=1 if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - if(iaptype.eq.1) then ! CQ apmask=0 apmask(1:29)=1 From e8bb7e74bc9c2fb4a84c62345ea9e44a7ea6b49c Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 13:29:32 -0500 Subject: [PATCH 099/239] Add routines for a (240,74) code. Hardwire decoder for wspr messages, for the time being. --- CMakeLists.txt | 5 +- lib/.fst240_decode.f90.swp | Bin 0 -> 45056 bytes lib/fst240/decode240_74.f90 | 154 ++++++++++ lib/fst240/encode240_74.f90 | 46 +++ lib/fst240/genfst240.f90 | 6 +- lib/fst240/ldpc_240_74_generator.f90 | 170 +++++++++++ lib/fst240/ldpc_240_74_parity.f90 | 423 +++++++++++++++++++++++++++ lib/fst240/ldpcsim240_74.f90 | 125 ++++++++ lib/fst240/osd240_74.f90 | 403 +++++++++++++++++++++++++ lib/fst240_decode.f90 | 16 +- 10 files changed, 1342 insertions(+), 6 deletions(-) create mode 100644 lib/.fst240_decode.f90.swp create mode 100644 lib/fst240/decode240_74.f90 create mode 100644 lib/fst240/encode240_74.f90 create mode 100644 lib/fst240/ldpc_240_74_generator.f90 create mode 100644 lib/fst240/ldpc_240_74_parity.f90 create mode 100644 lib/fst240/ldpcsim240_74.f90 create mode 100644 lib/fst240/osd240_74.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 20eb32034..87b8509ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -596,15 +596,18 @@ set (wsjt_FSRCS lib/wqencode.f90 lib/wspr_downsample.f90 lib/zplot9.f90 - lib/fst240/bpdecode240_101.f90 lib/fst240/decode240_101.f90 + lib/fst240/decode240_74.f90 lib/fst240/encode240_101.f90 + lib/fst240/encode240_74.f90 lib/fst240/fst240sim.f90 lib/fst240/gen_fst240wave.f90 lib/fst240/genfst240.f90 lib/fst240/get_fst240_bitmetrics.f90 lib/fst240/ldpcsim240_101.f90 + lib/fst240/ldpcsim240_74.f90 lib/fst240/osd240_101.f90 + lib/fst240/osd240_74.f90 lib/fst240/get_crc24.f90 ) diff --git a/lib/.fst240_decode.f90.swp b/lib/.fst240_decode.f90.swp new file mode 100644 index 0000000000000000000000000000000000000000..80719f14301320e718670170abe1f21b1c9edddd GIT binary patch literal 45056 zcmeI5d6X+xedpzbEtu72Si?|l2S2I1T2e{9y(Wb*&v*g+z|TuK;NhW`O5OFIy3|jl zcE9&#SWXfQWLN?O20RQ2F_W1Ph{Itr8Ngvl0^}SB%Rty6oWa9R!WzIPVLrd#y|+}_ z`q`fOCxg`I+p4a~|&;jNW}0-pyI3YR?Z_Gdok9-le)OUDX@wB2hY z$0Lc^_j5&~`S@=4_~KK0-EybfY;>lievTzrdHinNX{D9D^jQC7CG9mUop__tPW!c` z>d{uz?6#tE`(Sknm09qt2WCBRr+Z+x-(Fn1?=|&Wpbysh=goQNo^#EeCNs-0>w#Gh z%z9wf1G65O^}wtLW<4w&My_7OZ9)jHX*U!XN`Q{!`|Ouzq=#x_pgU$@^qTYxL)-Zot25L~}uB>wI;{yz5mVw#Gh%z9wf1G65O^}wtLW<4t*#nJM zp)g0ye<+MF`hUm&fAju@!Z*Ojz^lNEzz(<;Tmv2l{_%c=!bic|!0W*=a49$d?gqYc z-$LR2;MJfHt_D6h3w#$w{yX5S;49z_;5y)g1#oY0+u4P}C&1gmi@?*sW5A=p+2C6U z4L%6o1fCBLfjRIsgbg1C{|&qWycq0(O>hY)gC8QW_&e~|;Mc*W;9=mQ;A;pA{sw#q z{4sb7Xn_j24ME8Jz-dqcw;`Cg75ou+6L<-DF}Mai9$W+};B0U!LW*~TSA$o9=Yiwk zT5u8Y!9&1xGeYHJ7gD*K_G=qv?Xl>4MR8RhKUCYdLx= zUK(|xW@?DpDY9G&bJM{FGG}sQZv*R-0&9~3gGqr^3ADv; z_j;@Kur|NlZ58!;p?7`MEG{2hUtKNvwbG)SQQL!LtM#dgdcEF&SZ`{w<_VXodBP+L z)@ug`<;Cq{JMN|ZlGopg60Pg@DU6;vK|M4VQvKFR8?+Utazzl`o5cON(TPt-Uc1}# zcGHL;Z>P~beyqQ`s-*g)f3#%SAk+&V>$z)4DaA7|fGqUzg{ zt6H5#zhN>~%KhGMRIW&9?!&XlBWU3M^BijkOM;0R%_Ir)ndHvgyKk3bK*|vJE+|lV zOKRoGpjKQq6Ftc8G8#gIR3@GL&ymteqNGeVSN%K@LnzRunDRZQ&sZj#EY}>$&Sj#g z-aeUJMTawa+szYXy7PZpn~F|>IO#{5QE$HH#e2+#V!c|O4{FtFm4%Wn?Q}O|ri`5= zN!Lz-eAGsxm7YqP{%*2!e0B9`y4!3{H=E&M2qiJ!7M4`;Qj2zkj#*7Ln?+Z)Oe zrTXwd(M$V{KDX7y2!LgW?VF~tBvfcnO(K?%8~Rv z)+B5@`;CoGUMOdVrnkIR-@No=g{Mk@FuN;&G7_oozz-n(d-|ZEXh){EUdojZKs<)NTZ}b z7H2G1wa2wnc6!}r)Y|Pu#Uazyqi#hnNjJJ1rPkqr7*55@RAXgg{}oyI9Yo1^mT*^68D#pC)@>p}XY-SCt4hM%On8<36s zq!mRwe$wylM7_A%@{{P~j$L*L?RNa+^j3Om+b6HA?PTlG@;HgiIuI45{l4osUzb5Y z+3h#|p=Bm%pGdowNTJzH`i(eAr4dom(mw6A8_kG&J`$8GXYzQNq}f838yFpxtU)fF zJfowDPV8bGO@Z>U3+8ANI(FsRyQhZA% zvgDptpET+1M?l^sE`Ayb2FE37-pNT$#k`o+C2q!jFJY;4gb3{R`rgo3Wfdip?Hie# zzI6Lw#@U&9#sT-tOw*~QZ_I?Q@LPRf`qWKNud$K#WzosaDXJ(lO15JY>zAzz@-&-z zN~^L-$~8~-nU)XV+v!S&_eRzcEf&HfJyS5x^l)%N`2S1chtGy@7XE+U@{K=&zyCgX zGk6)e0jz@C;p@K#ZUzy!7TgD%4GQ2p@b;evw}5wo9dH>~2WJD}`QHM1;8(z>;NxEk zHb4bD65J2`i2A$@Y=Z{)HE=C>5_mND6`*zAkI$XO&3a(g1G65O^}wtLW<4*aI_6idzZ6{=VpODYcJ~W_7YE7MaZ?fo`mw@CTQvMCf zEhch}FgM(}9x2DrXYNRMcXP{&Qut3~86pX~>hO_5mS&6!66IFAHXrXGsmM~z9deEI zWZ%9UB~6v8m;_pUsQ(w7IGGr&d?BM@Lh>yzQE9DsycBLXP8O?WUvCzx<%9Fml=+jb zjbdDKT(C)x?D%+jGb+aouS~7V-tlsWyA2~tcAaI?9uKu03$=NX7|q8fbm;$_aKeLD zan;@Ss79_(h9C|X>;6K0DCfw{+>vOzi)fk3OD{KM3Pm07(4kAbhT{*ZJEXNvrSfLK z+}}c)w`FUdr#E+bsv-)=>~zyK7J*SVR2LRZQt6^FqnFPY8%JM`oyTyz*g+h(^H_qVpaewQao2gZ#EZHXGqE#xwhK4c6^ydkv;)(`f;(-}W=hY<=IHOU?ve$tJ})rqc;RCFSOA8)7Gmtm3#lr$Ff0jaOY$;P6& zEctRRQGp3r@#|GzO4nh|Kixv26sE=4W%U+3cUSTjxK#4F%lW#SD{)8>Qq-B6q$1B< zmN1!!jA2?Vc|8B#5<{FsD$JvUs^tQNAQx`O2@Tuu%}CaD1<*n%PnR1hH(0O{Q%aw^ zxSJg4d%fL+BHKE_Xt)+8<(N(o{{N$Ap<73{Ed0N-pZ^5BzVQAxf)qRz+!uTt9{=6o zMc^=a5cnB<{ingZ!0SK^t^^CyaK!soB%su3Dm(4(Bpp}h>rii zgXe+EKmZ;B?g2iDZvO+|Ch%Nv1T296EqZ+LGSC4bxDWUq`g+mte-?ZY+ydSLc0mYA z;K%gw2f*)vQ(zNlzyBQUOMc#(m_3vEwZ;S<50B@!8U*fa#kG)EZc#24TJqoT?{#-# zedaS#gaVoskvm@XADE)sorU5$b! zr3qB=F7c9%^s1Marg^3!QdO&pP<5-Hkq=O!qDIN?YkDu~o#s`mEdf>|>75Sz(>4Ee z-9NqLpVqyMi)r@vj@!wQ%P^z_^-Y%{jn8J&ddZE9Q(8_?o{r`VNNdM;IG5LKRcS-A zvl!@nyaS3qc4wl2mFc+e-@=I@FA!Bu+Ahz@+xDufZUI4db!6&jwtE#C)=Nt1U0M2>B**oUfZ0NaE(H zX2-E18Ih=yj)f7q*=74K^(|y6hcB$L)nw(=P*UCU4p{~jjZz9GMpk09QYS?%#R!RZ zI#W$)BFsTxu;YI3l@ru6++N{xq}eBmSRokdidD$d%dV#kyouM$L3N&W zC8!n~z0J~MjknBV5R_MKV3O{n75KKnyC)-UE_fA?QP?|4BRlw{Fp|XFk}6yhLi6-O zys3Paymj4Ma3mAWZgnS9BBf9W<=+A}C&oG@X33QI#pFEtLJlxZnH;V3rqo1dwn(C^ zvQpWhqrysKIf8Y~z&M8)46B5;Ki!!)%EIYNTsb`Z0H1z${r{KX z(S7)M;s0UH_46fo{l5mk2abUAf$09f0sbd=6L=-~w?Oj#5E>r_e+0Hb89W@^3c)`F zUGQ{J2M+^3g3tde@MdrWcotX#=YaRY>;ED6Eg(Ao$AJ5QFT>}*4*WVe3N8jdxHtF? zeEqw@%fSlxdwBSFgPXw1z#iBDPX#OBVc_22@8Rjc4ZaLM1U?8}23`uD0uF;Bcp&&3 zeEv;9?E8D50RnIy_-FWg;r)f@zX3cBTnN4ak1ss`Yb?Ki1>YBfWpDv_2)GycDE9lW z0lx{Z0_TC-k;{An`~`R$upc+1R)Uk=axr5qv)-7omNV8;`OpEcH)Acucz4EHvWuFr zmUf{un+Vj1nbXOPwRG>08EZ*T%veih^Jc82WlLwQrCT2K`~OeYa?ms*p0M2IP|H#L zqlnMP7x5|bpA@y*K61%!iUb(_Pt?OzQ5>QMj#YR?S+Bi3L6bOKD&zyX7J}i*Sny=- zcU&Z3s**XX8sd}W1Y-p82Aj%G(}HOn^+@$cdP&^O?oc<8a6%_duH+qT^(0}0=>N}! zvAh(1Q~3WIER*?Z`29ZtH-p!M7lV_a3lbnQfjW3FkaGaUCg4xNe*$6~@Ir7Mcm_BG zL`EQI0=yNOz<&V$9$X8a2p$U_3BHM3K+XYp4tN@=+c{sNi8TfmLrwcsR>GX<^&E8tvk4)`%Lh7SNaPv9kB4?GL}8jy1ZL z|A36)3*f`xZQzaI1z;Dn!IQwRf_d-=a1MAN_)F%+3qc#m9JvHc_%P|MLtuitU$79Y zn{Vv;tS;6@+lW$VyjR_AVNUH~8lAMOnkZ2};SO_s)Wh*>vyy3}#8OHPpfc4^nXFf1 zJB6d6N73kj&|Tpx){db``6Q$J-o zA-gQq3+A~tniCckV>?A)vVk3$RWr-FA|gHUaI-?;oY4M^q{u3oGn>;Ab|vpu4t8I6 zq#P%|pIDAP>tN1HcDFZB2x6wBEko~j8Yf$nS*Va~FXZczZ!cD6S`SHiEagc$E5BWUj>Yi!V zy{7R$t*!?vRWSoV&1w|?xg?@Qmg!#8NHc|U(as0fBnm1FmNs>eWcb-w&;-(j$yN~R zb5ud;>3JF?kCz74<`a1=Twu+n)Idp{|IBSSj-&0x7nSj8U{WVk zquWWnqA>(%^=nG9o$BlqD-8;0r#Ui1mvdLCR$BG@Jxnqk9jQswG@3wYX%F)qw$n=1 zPwg~RSNZZZ<3>lETB}Nz0oNuDNHDA62MVT2+Kt!%_KU@YC1DY5Z^_AQLI9Rn@v7t1qp|*SG4gVQ{gsh&S>%O6v0Cwd`tC)95uh&#FTi4o-m7_XmqpMX$<)E6I zNpa$SzL4+_M_xVnLdwOO;9$wRNffBJtOp!7!<)r8$L9_^a)%yG`j)Ku*@OH}ID=|v zFC?CiJpsWTOB3j_Ctk*CJX6p#x|q0QLa<8KV`Vs1q!eP+Zc>;qs@dGjj@*&rsDdcb zgVm*@2Lq=PMP1w6b1!(Ou3c5L#q4fGTZ-itc5SNX&2+5x5DsVLM~B9BQD_9la;}K> zS#J4~vlvPyw48MNd|)a3?xUQD46ONcYav8%}#I$&AB~xNQiM1?C8p2 zDRQ2JDa&l4cel4sxpWxW*r+`<3*U&uJ%PQi8l6LrF6NYh;&AOs)_1@?EBSJV=UT3! zZMN}IS$EPSbZtj4T(~57>=v`ZDUg!S^y!DI$JmT?kG3JJ^FdEy!ev9uD{TcO+;!IA zsh8#k62(epV+mL%%@2$@)Wl|zL)7fiZSK{RoyEgWW6}|CORE2e9WC5b z_&WH1cRv0P;OoT(K+gYrJ8-gqS9ASbZ~{CNEP->uJ;Ar(@5MjhFTp#&+rbUsde8>f zfQy010}g@;cr2NF7OZF<3MBr z{}DVFG{Mt>_!T@3tbm7uhk?()_kSAvE_gk7E_fC=3gmo&gWw$Si{LhR{#(IEfXE15 z0h-|H;7QzeHSmw{@E-^N1snyB0c9`;9tMQ3{|#_8xCoTNqrn{b7-RbakbrBzxj@GI z9>9Lgv|?)J?ZWVVQO_8BUwCCX|wT;P&+BOaRY2ZWE@27#y>8TV}Wsk?PyT`s?Pqs;|IVvpvP`nh8B6HyD z44=%pxzpWS#Fechhs?mL7;{)B5GX)Jkbi2$Lq{zR+gt7xAbvR}sN;g#TVCjiBad*s zWz1rmyr`nyf;Q{u#$KgXF41_m32JvFIi7@Y!-Ld|qp4Zu_o4&5d()`V6Gt#aB&Mez zDHY{oOA3qa#sbVX1x?|1<}Pn%dA-MGT?r+>0G%8!E=`U%B#@6ZHf|K;3Ij#k|6~$F zMOWX!LhC{}n+Sdq&XNoyCiloE=Qp_7g-sGOYYYK#{!*vGTtVs|<+^pFw3zEQBSpwc z376)JmgTDmhgedEwm`}F$?1UQM~J>+KypV_Ne$;Ni#NA&PL`c`+nD*`PiH6$2CXrP zfH(JK=56MC>P9Z3!-IjDVa4n(TjIeg&x91c&u30t$kN?y>uR~(NKPRFOHvivAPT$W zlB)}3hgc|FyUYQ(R}NlSV)}yH>7ThLMW;kc<~U($q^z{?83nTCL=*Z_QqKTo15Qh{ zT3(pjAv=GZVk^~hZP~}ifMf8=tGvLN?RsH@YRdz2e(|AQtgo|CnEsi&LVZ=27R5d^ z^Yl!m7U~j!gP*$5?Mox)m$!%OW!^E*5IHjqGt4X`-OjXyL`h|mOLsQggr?0Mf(y|D z+|=@2+5$H(=l*dP5<8&@S+bzHOE_ARCjzNtKA%b+vP2Uuq#so_${MIUA0#V=DbW=z zb9$H{&KjaNcgZfx6I;nm`jKfUGqTs%(A%LNp}dY$(&aAzT9UJY6k>v2F9-Q(k>+p9H-P3S^hyi52S z>g%~?t*LF&(>X;Xiuon-=55XvD+rk&Yz7t0Ew}miDNAKsU5u@TXET676p0~k*zD~o z@$T)R$roaA57(xO)R0WW$rns=XBBK-07^G63^WyE>zXggjH!4^Npym=FWy>=tH#VZ zW`6R>F~@MBI8&t{G|-XTzxD~oT^P+Z7ePbsgULiM&t6E8Hztm)pobVeWw^NFU0A( z{$CLP9V_ylM`&#+ej{Hx+{B0 z%a;GS?4_Zy@g|&F_Gx;`k*X^x`9GD^e$6;d$2w9qB_;o-lG?9UqkYY=ILd)imj6>J z?^j9bYsoB23d>ZEML*4RU7&OM#A%3Ydw@LJj%I;Cw_qSJm)k@H=SW>ip${xm)hg|n znC_~cU5TT*l247JrI3i1Ls>kQ(IFVW(0EA$f~72=E&;16*?mp!>*`yn6yUd~Y*V4n zhy6P4T`2}hy~Zg$$Z=>>Zan|OwrjX?-mHbw`-c=gdWSlAOUbR`mbE2A(7T;Q!t4_kA9I{tZCv|F^*fKzRIn zfFHx7e;s@cd=7jV2+#jNz#D<^{Bky63p@&Z7ry0Zv2M+>g zfgi%he+J0e0nY&IpbF$S1H_l$pWx}g1l|tb2%ZnF13vgR{JfkWAUgf$fdmN8e-(Hl zxE#pu1uTNQgCD@-zaP8yQ{^P+z!EKE5yTD1X2c8b(w-9ywRT#hw zGap%BjJn$@q+^beNFx+<1(!r-X)X<-G?&IbhBEgJk+AA#%5z<2AY!&%>OFc?Ucu&l zKIQG~+y&iBI`g)n5@W)B{2^KR(hUv|g1J}6bI}hfGh9Nw=-BRjI-^3&#~K1=Gc?$( z7L7~g5>D7gIKWrt%ovWPtGkC%_6g(BrWw*tl2bhEzg%MoOR5sk3OWPxN6!eO_)bD&gOR0gL*+?c*LZs1yf<|d35D=e%MxM zBPS3R{%SzFJz?G%!eiq($Ie!d9Ks2aLwDuetwHAxM%lBq8pLH!MQEBkEdgVfJuEg& ztM5F4L(e_5qQmD^h~dLrf)EIyk%yfDa=-uq3focGJ4}V-0Bku1zSn1C(6{^m?#1r$ z&Prl`-fjvnLl@gpMH+2o?+*vLr};^nQK~z+(=ige5ABgNXqk~B}{lgNk1||83pYnt&|&rEQ$*|T>DmP zZF;5FT&0GU^;rqp{Zjkv*n=A9NyrpL#A}2RYgT~31`MbCntIW%x##%K5OR`;JfRT> zPkDf~bUha;pejfa(ycu?9V8>SkPn@1mwO4Kl3|dEXHB4nlXPi9_>ip}ZMDnJ z@QfIQ4^Lkvpa{h5#)i(wKhLIY8<@-ItV7hJ%w`>XuSk=FDJ>3iYm000gr;dfW*xvq zA%DZQj4IpyWp@0ssTq&9f*E&IzfD&fCZx?7p=@q>^BL{JPG=X1GU7xG23UDH7bf+L z8Uve2Wx`z&N6^{_#$>Z)15KTa}0ILgm~;PCMjS5>fBhJQet6t&zbS zny=8!hAp?9A%i|ZJkIP--B?dvVX?Bd?Ywi_)=a9zPOo5$RmG%I{^8WpCBSj+Nj3Me%4r)o+y1~2l#jz>~o zO!cfKuA0*hs_QkplpR9W5T`O5njw&Oz1E84=Sqh6H?mF1_VK)+$72V|L8)PW`y+2) z23f{LUo+;?t^Ue@xc8G;rR-4)AyycY$(^ErtVC}0qkHcOf@%BK{l5@Oi&%QjyENh# z3-s7Tep;*7Jt+s9TKmXs0J8p%BO~T;0%9v?7_}B%ua$foR&!?8gz5Xn%v2-SHfgNH zGw>HVJjwX~pMqa)!0QVCUsoOwz8*gR-QXthY_JLb6}Sz4{wF|q|965D-~jjny!r;630KpaoXIy@1&9zYB=%zMT8N1Re^$0grwQcqtHl{KeqG;A`;e?*K0b zJD>}m2p$3C+`o^2KL@vf-vz$~PJj&{?Rp38`+e{tAm;$c82}dp5BwNj{G&kh@m=s> z@aOR0F9+8HvAHjS2Z8&7Pr`4%6Wj=n1F^Bc8ay2Q4F39y;AY_X@55Zzf!Nc389rNn zw@+;8F8~h&KRb*50G|T4fY$>3xEU$m!zN85_97->?i7hp)<_QW8D0!C+J)?ji}Ba@ zv_QgTJvBc#CNIL3k|#ebWPX_~6n~%1dHpf2Vz6$19x7kbSbnVW#`DWhOWmQ|7!8i+ z*59g{l3h}Be#lzMR@GV^X;5LLqTJdabTX%yxOYT8nMshzT(hX*PFgZnNx5!Y9t!bn zPs*0U8!Snd+QiWz?yj~)T7TEuVh#Oa&PINQk>4LIc!jJ7%*Fn7=cmO+$AO?x8c@o{ zL2}&nx?5>LuI}=qiCS^3?r6z(wD$5dY5G%vqXhonRXy7b(eH<@94#j|-B1bC-O+)W zMW-+}P|!onAaIypM`CZsZ|cB5BrQ(<;@CI+*~0w^*MKrQWYiW2yIT(|GFr+BA~7G1R6; zf%=&bJ>S^BO?d&7Nxfg2#!~Owrt#GKwJD$4JxXD%yap5Fnj;(4!2y>lQe9%dXx@QY zqU>Vs{PWNEu9Y7fU_;<>Gaxjef?_pTNU*#}u*^uX+(?YMhoQnv*yOzbe$oCwXq9J{ zXH6EOqW$$(u`H6Gh&BJ^_h8l5NbI+B?*>Q@QL5E=o~gZ|WOHa?(<(C;^e-hWui@}&H`7SC&6W;ipTOwdqgo=EigopJx{g zv5-@{5m;hbgDFMkZaSz96(vf=Vq-NO2s#(63U)Z(K#|M#*C}c7S`q#KKfwoo0X|vy ze_m1g`6|5rUxAl`r-AdpKf~vL1^f*V-v4)i`1y;T|5t(h7J%68zYRPcoCW?Ce*Ycd zwO|{FU;mZh;oxWR{9gn&gB!tXz%#)ia31(Ry#E)$7r-mP9+2|@4*-z~ya^lw*MLKy z3PdJQ0NNhgmf6>=2WCAm>w#Gh%z9wf13yPSU^e9D|4fFS?+vbHH#v~t&t&L#K_4)a zp(E|R;?yBI3t%QgpUKdjtbHa!FXR_nS!qRYK(|bnp^L1: do bp and then call osd maxosd times with saved bp outputs +! norder : osd decoding depth +! + integer, parameter:: N=240, K=74, M=N-K + integer*1 cw(N),apmask(N) + integer*1 nxor(N),hdec(N) + integer*1 message74(74),m74(74) + integer nrw(M),ncw + integer Nm(5,M) + integer Mn(3,N) ! 3 checks per bit + integer synd(M) + real tov(3,N) + real toc(5,M) + real tanhtoc(5,M) + real zn(N),zsum(N),zsave(N,3) + real llr(N) + real Tmn + + include "ldpc_240_74_parity.f90" + + maxiterations=30 + nosd=0 + if(maxosd.gt.3) maxosd=3 + if(maxosd.eq.0) then ! osd with channel llrs + nosd=1 + zsave(:,1)=llr + elseif(maxosd.gt.0) then ! + nosd=maxosd + elseif(maxosd.lt.0) then ! just bp + nosd=0 + endif + + toc=0 + tov=0 + tanhtoc=0 +! initialize messages to checks + do j=1,M + do i=1,nrw(j) + toc(i,j)=llr((Nm(i,j))) + enddo + enddo + + ncnt=0 + nclast=0 + zsum=0.0 + do iter=0,maxiterations +! Update bit log likelihood ratios (tov=0 in iteration 0). + do i=1,N + if( apmask(i) .ne. 1 ) then + zn(i)=llr(i)+sum(tov(1:ncw,i)) + else + zn(i)=llr(i) + endif + enddo + zsum=zsum+zn + if(iter.gt.0 .and. iter.le.maxosd) then + zsave(:,iter)=zsum + endif + +! Check to see if we have a codeword (check before we do any iteration). + cw=0 + where( zn .gt. 0. ) cw=1 + ncheck=0 + do i=1,M + synd(i)=sum(cw(Nm(1:nrw(i),i))) + if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 + enddo + if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it + m74=0 + m74(1:74)=cw(1:74) + call get_crc24(m74,74,nbadcrc) + if(nbadcrc.eq.0) then + message74=cw(1:74) + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + nharderror=sum(nxor) + dmin=sum(nxor*abs(llr)) + ntype=1 + return + endif + endif + + if( iter.gt.0 ) then ! this code block implements an early stopping criterion +! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then + nharderror=-1 + exit + endif + endif + nclast=ncheck + +! Send messages from bits to check nodes + do j=1,M + do i=1,nrw(j) + ibj=Nm(i,j) + toc(i,j)=zn(ibj) + do kk=1,ncw ! subtract off what the bit had received from the check + if( Mn(kk,ibj) .eq. j ) then + toc(i,j)=toc(i,j)-tov(kk,ibj) + endif + enddo + enddo + enddo + +! send messages from check nodes to variable nodes + do i=1,M + tanhtoc(1:5,i)=tanh(-toc(1:5,i)/2) + enddo + + do j=1,N + do i=1,ncw + ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j + Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) + call platanh(-Tmn,y) +! y=atanh(-Tmn) + tov(i,j)=2*y + enddo + enddo + + enddo ! bp iterations + + do i=1,nosd + zn=zsave(:,i) + call osd240_74(zn,Keff,apmask,norder,message74,cw,nharderror,dminosd) + if(nharderror.gt.0) then + hdec=0 + where(llr .ge. 0) hdec=1 + nxor=ieor(hdec,cw) + dmin=sum(nxor*abs(llr)) + ntype=2 + return + endif + enddo + + ntype=0 + nharderror=-1 + dminosd=0.0 + + return +end subroutine decode240_74 diff --git a/lib/fst240/encode240_74.f90 b/lib/fst240/encode240_74.f90 new file mode 100644 index 000000000..1d555d17f --- /dev/null +++ b/lib/fst240/encode240_74.f90 @@ -0,0 +1,46 @@ +subroutine encode240_74(message,codeword) + use, intrinsic :: iso_c_binding + use iso_c_binding, only: c_loc,c_size_t + use crc + + integer, parameter:: N=240, K=74, M=N-K + character*24 c24 + integer*1 codeword(N) + integer*1 gen(M,K) + integer*1 message(K) + integer*1 pchecks(M) + integer*4 ncrc24 + include "ldpc_240_74_generator.f90" + logical first + data first/.true./ + save first,gen + + if( first ) then ! fill the generator matrix + gen=0 + do i=1,M + do j=1,19 + read(g(i)(j:j),"(Z1)") istr + ibmax=4 + if(j.eq.19) ibmax=2 + do jj=1, ibmax + icol=(j-1)*4+jj + if( btest(istr,4-jj) ) gen(i,icol)=1 + enddo + enddo + enddo + first=.false. + endif + + do i=1,M + nsum=0 + do j=1,K + nsum=nsum+message(j)*gen(i,j) + enddo + pchecks(i)=mod(nsum,2) + enddo + + codeword(1:K)=message + codeword(K+1:N)=pchecks + + return +end subroutine encode240_74 diff --git a/lib/fst240/genfst240.f90 b/lib/fst240/genfst240.f90 index f60dc8446..adb8d20ec 100644 --- a/lib/fst240/genfst240.f90 +++ b/lib/fst240/genfst240.f90 @@ -71,7 +71,11 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) 2 continue - call encode240_101(msgbits,codeword) + if(iwspr.eq.0) then + call encode240_101(msgbits,codeword) + else + call encode240_74(msgbits(1:74),codeword) + endif ! Grayscale mapping: ! bits tone diff --git a/lib/fst240/ldpc_240_74_generator.f90 b/lib/fst240/ldpc_240_74_generator.f90 new file mode 100644 index 000000000..0cd5db01e --- /dev/null +++ b/lib/fst240/ldpc_240_74_generator.f90 @@ -0,0 +1,170 @@ +character*19 g(166) + +data g/ & + "de8b3201e3c59f55a14", & + "2e06d352ebc5b74c4fc", & + "2e16d6cf5a725c3244c", & + "84f5587edca6d777de4", & + "e152b1e2b5965093ecc", & + "244b4828a2ccf2b5f58", & + "5fbbaade810e123c730", & + "6b7e92a99a918df3d44", & + "bbcec6a63ab757a7278", & + "f5f3f0b89a21ceccdb0", & + "a248c5f1ec2bc816290", & + "c84bbad839a5fe76d0c", & + "ad724129bbf4c7f4570", & + "91adb56e7623a2575cc", & + "cbe995bdf156df2c9e4", & + "92ff6ea492c08c150e0", & + "c4ddbe5a02f6a933384", & + "d2e9befc131dc483858", & + "68567543d1eebcb080c", & + "21fa61d559f9baf6abc", & + "911c4fbbafc72e3db28", & + "7c0b534af4b7d583d50", & + "12ce371b90ee9dfe72c", & + "15a604148872e251ec4", & + "3a3c9f3eb0e0f96edc0", & + "705919ffb636f96b390", & + "43daaaa8163d6bc2bd4", & + "96e11ea798b74b10e98", & + "811150609c9dee8230c", & + "be713f85ab34380f4b0", & + "5a02c4abaaccb8f24c4", & + "67bdebb8863d04768cc", & + "5a449cd90c3dbdfe844", & + "9c7a54d1c4ef7418b84", & + "cd82fefaaf9cd28cd8c", & + "ca47e847fabb0054a38", & + "f0b30cef6aab9e37f98", & + "d948d912fbcc1708710", & + "cce1a7b355053d98270", & + "4cf227c225a9063dd48", & + "2db92612e9ba1418e24", & + "3d215c04c762c3d6a28", & + "77de65500b5624ceb0c", & + "fd1a1df99ded2fb9d88", & + "2a19392c71438410fb8", & + "a9b486a9d26ed579754", & + "b698d244ac78d97a498", & + "3d7975b74d727a5e704", & + "38094225a2bce0e1940", & + "3d3e58fae40fac342b0", & + "7732e839a066e337714", & + "69356c082b7753a47b0", & + "3e868a55dc403a802ac", & + "a0157a14a6bf7fdbbcc", & + "1ab628e11a7ab4a7c44", & + "9da3a2247d7449052f4", & + "199a8a7b114816b97f4", & + "b1c5cde2542061704cc", & + "432fa8d3a153eafbdc8", & + "c4ece7e400d8a89c448", & + "316ecf74e4b983f007c", & + "6a14fa8e713bb5e8adc", & + "da4b957ded8374e3640", & + "0a804dba7c7e4533300", & + "52c342ed033f86580e0", & + "1667da8d6fcf4272470", & + "da2f7038d550fa88d8c", & + "685bcbab1d9dd2c2a44", & + "4c93008b3156b3636bc", & + "726998d6327ac797c3c", & + "44ece7e400d8a8dc448", & + "01f9add00dfe823a948", & + "dbb95f5ce9e371ad720", & + "fc746ee5c76827a8728", & + "b25408029506467f4b4", & + "9b5c9219e21126b7cf8", & + "39ae9f48ba9d1a24f04", & + "7de2699623eb507f938", & + "b9c6e903ee91dd32934", & + "397510d2c6cb5e81de8", & + "20157a14aebf7fdbbec", & + "067f76ea5817a465980", & + "9248f3cea0869feb994", & + "23cde2678004ebe5f80", & + "5b81fe6848f58e3cfa8", & + "a9099ace96bff092904", & + "4afa4b0802b33215438", & + "f4f740396b030360858", & + "fc613f77a35ee1163b8", & + "1a4dc27d7e8cc835ff4", & + "e9b056f153b39def7ec", & + "b62eb777a2f953c7efc", & + "388ae4de514b62d238c", & + "891529af40e85317160", & + "474f1afeb724dbd2ba8", & + "11d70880fd88fdd307c", & + "29f26a3acb76e6a517c", & + "df3e902ff9cadcf776c", & + "e3c42da8445965c09f0", & + "ce277a6aeccc316dc58", & + "4d7841fb71543abd9b8", & + "e63230d2d465fb44750", & + "b6e11fa798b74b14e98", & + "05f189d37c5616547b4", & + "ebdb51a81d1e883baa8", & + "bf5bc736663bcd53ae0", & + "2f8d1cc0936142c08fc", & + "436b22fc36d917b6928", & + "044b482822ccf2b5f58", & + "37b2e839a066e3b7714", & + "2a9b4b765c581f0c51c", & + "10a7d44cecf8e6628dc", & + "ad95f02df6d5502dd4c", & + "bbd34f8afd63deaf564", & + "cabddfeb01fce632788", & + "66b57babeedd6124114", & + "7813e0454fbd462be8c", & + "b6105ed6f01ea621d04", & + "9f68bbcec679d1c088c", & + "673da96e414fc7a0f40", & + "5568adb935e11084abc", & + "f6dd308de5e5c4f6fb0", & + "3b49e80d40ae596c7b4", & + "a3cde2478004ebe5f80", & + "dd8e4f309e919d5ed94", & + "5a4020d387757d7bc28", & + "64f9e02ae32362a255c", & + "630d5942d392334b0dc", & + "0bd7e9f4229b2dee210", & + "bca549a9467d3a2550c", & + "2fef7b1f578c5e28d04", & + "f35e0fdda1be4b3b35c", & + "69ed575e7cc537d2394", & + "7dfdcfbfd5ef3093680", & + "b3b2921af97f251d328", & + "5622d0fe90363522364", & + "fcd4fc7fa04a69d2ac4", & + "1119ea451502ed9ab34", & + "970ee777ec969a41754", & + "688d14f8afec76783dc", & + "4d0b8a1028578407420", & + "d3d2138d9fa268da3e8", & + "df1bdbff898e006394c", & + "8ac478a916bb0b77684", & + "93881997428e2c17a94", & + "4aa510e746245e90c08", & + "e00cb8543f85a5d58b8", & + "9100d8eb74031073044", & + "38710e4235bd1e4003c", & + "6aef311cac4c4dccfd4", & + "58430f577f51c36b3e0", & + "12082fa5d4268a95b4c", & + "7a7435a0aca071e64d0", & + "cd8250ebadc95de15b0", & + "debad40c852e99d64dc", & + "4e6caa5e7c86efef748", & + "a5d4cbb97e726e3c580", & + "7e3a0a2c73ef8553640", & + "b60bfc2fd2bd8f530dc", & + "32dbef097a5f84b0318", & + "4cc7c1cf434300be380", & + "896840945be8eabf7f0", & + "36c9b10ec694819a0a0", & + "349f46a799ef95a47c8", & + "9bdcd4ce2563e560b74", & + "b19fcd7111a335c52ec"/ + diff --git a/lib/fst240/ldpc_240_74_parity.f90 b/lib/fst240/ldpc_240_74_parity.f90 new file mode 100644 index 000000000..6d41fde54 --- /dev/null +++ b/lib/fst240/ldpc_240_74_parity.f90 @@ -0,0 +1,423 @@ +data Mn/ & + 84, 101, 144, & + 10, 14, 138, & + 87, 148, 166, & + 1, 50, 67, & + 2, 53, 74, & + 3, 83, 113, & + 4, 90, 121, & + 5, 63, 128, & + 6, 124, 138, & + 8, 22, 108, & + 11, 28, 159, & + 12, 18, 142, & + 13, 24, 145, & + 15, 131, 149, & + 16, 44, 93, & + 17, 41, 47, & + 19, 37, 129, & + 20, 33, 94, & + 21, 100, 154, & + 23, 71, 141, & + 25, 89, 95, & + 26, 105, 153, & + 27, 36, 58, & + 29, 59, 166, & + 30, 52, 126, & + 31, 61, 77, & + 32, 84, 111, & + 34, 97, 155, & + 38, 98, 127, & + 39, 76, 143, & + 40, 55, 92, & + 42, 147, 158, & + 43, 82, 148, & + 45, 49, 109, & + 46, 70, 86, & + 48, 78, 139, & + 51, 101, 104, & + 54, 63, 96, & + 56, 81, 125, & + 57, 117, 164, & + 60, 75, 107, & + 39, 62, 132, & + 64, 110, 118, & + 24, 65, 146, & + 66, 80, 134, & + 68, 91, 114, & + 69, 123, 162, & + 72, 88, 152, & + 79, 99, 130, & + 85, 112, 124, & + 99, 103, 157, & + 106, 115, 133, & + 116, 120, 140, & + 119, 161, 165, & + 64, 122, 137, & + 34, 89, 135, & + 136, 138, 163, & + 93, 144, 159, & + 35, 130, 150, & + 62, 151, 164, & + 104, 153, 160, & + 1, 106, 166, & + 2, 132, 152, & + 3, 11, 105, & + 4, 18, 160, & + 5, 53, 91, & + 6, 109, 141, & + 7, 111, 113, & + 8, 54, 136, & + 9, 61, 92, & + 10, 40, 101, & + 12, 30, 146, & + 13, 37, 82, & + 14, 29, 95, & + 1, 47, 131, & + 2, 8, 139, & + 3, 58, 130, & + 4, 96, 115, & + 5, 119, 129, & + 6, 60, 148, & + 7, 95, 163, & + 2, 35, 56, & + 9, 67, 79, & + 10, 75, 122, & + 11, 17, 121, & + 12, 137, 145, & + 13, 36, 152, & + 14, 15, 155, & + 15, 134, 143, & + 16, 106, 125, & + 11, 106, 157, & + 18, 99, 118, & + 19, 50, 94, & + 20, 126, 158, & + 21, 41, 135, & + 22, 24, 71, & + 23, 42, 136, & + 22, 109, 161, & + 25, 39, 46, & + 26, 45, 55, & + 27, 77, 82, & + 28, 73, 166, & + 29, 69, 76, & + 30, 108, 150, & + 31, 91, 146, & + 14, 32, 147, & + 33, 35, 107, & + 34, 103, 111, & + 8, 94, 122, & + 13, 70, 151, & + 32, 37, 142, & + 3, 38, 87, & + 25, 51, 92, & + 40, 57, 72, & + 21, 108, 153, & + 23, 26, 142, & + 43, 44, 48, & + 30, 43, 62, & + 7, 45, 154, & + 16, 46, 149, & + 1, 53, 75, & + 33, 44, 160, & + 49, 86, 157, & + 19, 80, 159, & + 51, 116, 138, & + 52, 92, 98, & + 6, 12, 47, & + 54, 83, 101, & + 24, 55, 102, & + 56, 63, 120, & + 17, 57, 82, & + 38, 154, 162, & + 59, 74, 151, & + 53, 144, 164, & + 61, 85, 117, & + 62, 66, 90, & + 48, 113, 145, & + 64, 65, 128, & + 27, 29, 65, & + 58, 63, 134, & + 9, 74, 83, & + 68, 109, 113, & + 41, 61, 69, & + 36, 60, 155, & + 42, 64, 144, & + 40, 90, 130, & + 28, 110, 135, & + 20, 59, 112, & + 70, 110, 124, & + 54, 76, 105, & + 4, 77, 111, & + 78, 104, 143, & + 66, 67, 91, & + 80, 81, 88, & + 50, 101, 132, & + 71, 97, 120, & + 72, 131, 158, & + 84, 133, 141, & + 5, 85, 99, & + 49, 89, 133, & + 87, 132, 140, & + 34, 88, 104, & + 89, 105, 147, & + 6, 76, 102, & + 18, 31, 163, & + 52, 96, 140, & + 93, 102, 165, & + 79, 104, 165, & + 81, 100, 126, & + 95, 121, 152, & + 97, 123, 153, & + 37, 98, 114, & + 8, 91, 155, & + 100, 114, 160, & + 2, 26, 28, & + 93, 116, 150, & + 68, 103, 166, & + 78, 117, 125, & + 86, 107, 127, & + 4, 59, 136, & + 9, 37, 97, & + 7, 30, 75, & + 80, 148, 153, & + 73, 138, 164, & + 10, 39, 103, & + 39, 146, 156, & + 48, 129, 136, & + 5, 17, 51, & + 112, 149, 161, & + 11, 24, 126, & + 1, 70, 78, & + 14, 113, 118, & + 10, 119, 141, & + 13, 33, 105, & + 19, 57, 89, & + 12, 25, 56, & + 16, 18, 54, & + 84, 124, 162, & + 20, 41, 134, & + 15, 45, 82, & + 115, 118, 123, & + 128, 139, 149, & + 127, 156, 159, & + 21, 141, 152, & + 23, 130, 156, & + 3, 160, 164, & + 22, 90, 110, & + 35, 61, 109, & + 31, 87, 158, & + 42, 60, 106, & + 137, 140, 157, & + 27, 114, 124, & + 32, 62, 125, & + 34, 38, 128, & + 40, 123, 139, & + 29, 66, 86, & + 36, 52, 161, & + 43, 63, 133, & + 46, 73, 108, & + 44, 135, 146, & + 47, 115, 127, & + 49, 74, 116, & + 58, 102, 122, & + 55, 85, 132, & + 50, 65, 150, & + 67, 145, 162, & + 53, 71, 77, & + 69, 88, 142, & + 68, 72, 93, & + 9, 64, 95, & + 92, 94, 111, & + 81, 83, 119, & + 98, 143, 163, & + 73, 79, 96, & + 35, 129, 131, & + 99, 100, 151, & + 7, 112, 159, & + 117, 137, 156, & + 120, 147, 154, & + 107, 121, 165/ + +data Nm/ & + 4, 62, 75, 121, 191, & + 5, 63, 76, 82, 175, & + 6, 64, 77, 112, 206, & + 7, 65, 78, 151, 180, & + 8, 66, 79, 159, 188, & + 9, 67, 80, 127, 164, & + 68, 81, 119, 182, 237, & + 10, 69, 76, 109, 173, & + 70, 83, 141, 181, 230, & + 2, 71, 84, 185, 193, & + 11, 64, 85, 91, 190, & + 12, 72, 86, 127, 196, & + 13, 73, 87, 110, 194, & + 2, 74, 88, 106, 192, & + 14, 88, 89, 200, 0, & + 15, 90, 120, 197, 0, & + 16, 85, 131, 188, 0, & + 12, 65, 92, 165, 197, & + 17, 93, 124, 195, 0, & + 18, 94, 148, 199, 0, & + 19, 95, 115, 204, 0, & + 10, 96, 98, 207, 0, & + 20, 97, 116, 205, 0, & + 13, 44, 96, 129, 190, & + 21, 99, 113, 196, 0, & + 22, 100, 116, 175, 0, & + 23, 101, 139, 212, 0, & + 11, 102, 147, 175, 0, & + 24, 74, 103, 139, 216, & + 25, 72, 104, 118, 182, & + 26, 105, 165, 209, 0, & + 27, 106, 111, 213, 0, & + 18, 107, 122, 194, 0, & + 28, 56, 108, 162, 214, & + 59, 82, 107, 208, 235, & + 23, 87, 144, 217, 0, & + 17, 73, 111, 172, 181, & + 29, 112, 132, 214, 0, & + 30, 42, 99, 185, 186, & + 31, 71, 114, 146, 215, & + 16, 95, 143, 199, 0, & + 32, 97, 145, 210, 0, & + 33, 117, 118, 218, 0, & + 15, 117, 122, 220, 0, & + 34, 100, 119, 200, 0, & + 35, 99, 120, 219, 0, & + 16, 75, 127, 221, 0, & + 36, 117, 137, 187, 0, & + 34, 123, 160, 222, 0, & + 4, 93, 155, 225, 0, & + 37, 113, 125, 188, 0, & + 25, 126, 166, 217, 0, & + 5, 66, 121, 134, 227, & + 38, 69, 128, 150, 197, & + 31, 100, 129, 224, 0, & + 39, 82, 130, 196, 0, & + 40, 114, 131, 195, 0, & + 23, 77, 140, 223, 0, & + 24, 133, 148, 180, 0, & + 41, 80, 144, 210, 0, & + 26, 70, 135, 143, 208, & + 42, 60, 118, 136, 213, & + 8, 38, 130, 140, 218, & + 43, 55, 138, 145, 230, & + 44, 138, 139, 225, 0, & + 45, 136, 153, 216, 0, & + 4, 83, 153, 226, 0, & + 46, 142, 177, 229, 0, & + 47, 103, 143, 228, 0, & + 35, 110, 149, 191, 0, & + 20, 96, 156, 227, 0, & + 48, 114, 157, 229, 0, & + 102, 184, 219, 234, 0, & + 5, 133, 141, 222, 0, & + 41, 84, 121, 182, 0, & + 30, 103, 150, 164, 0, & + 26, 101, 151, 227, 0, & + 36, 152, 178, 191, 0, & + 49, 83, 168, 234, 0, & + 45, 124, 154, 183, 0, & + 39, 154, 169, 232, 0, & + 33, 73, 101, 131, 200, & + 6, 128, 141, 232, 0, & + 1, 27, 158, 198, 0, & + 50, 135, 159, 224, 0, & + 35, 123, 179, 216, 0, & + 3, 112, 161, 209, 0, & + 48, 154, 162, 228, 0, & + 21, 56, 160, 163, 195, & + 7, 136, 146, 207, 0, & + 46, 66, 105, 153, 173, & + 31, 70, 113, 126, 231, & + 15, 58, 167, 176, 229, & + 18, 93, 109, 231, 0, & + 21, 74, 81, 170, 230, & + 38, 78, 166, 234, 0, & + 28, 156, 171, 181, 0, & + 29, 126, 172, 233, 0, & + 49, 51, 92, 159, 236, & + 19, 169, 174, 236, 0, & + 1, 37, 71, 128, 155, & + 129, 164, 167, 223, 0, & + 51, 108, 177, 185, 0, & + 37, 61, 152, 162, 168, & + 22, 64, 150, 163, 194, & + 52, 62, 90, 91, 210, & + 41, 107, 179, 240, 0, & + 10, 104, 115, 219, 0, & + 34, 67, 98, 142, 208, & + 43, 147, 149, 207, 0, & + 27, 68, 108, 151, 231, & + 50, 148, 189, 237, 0, & + 6, 68, 137, 142, 192, & + 46, 172, 174, 212, 0, & + 52, 78, 201, 221, 0, & + 53, 125, 176, 222, 0, & + 40, 135, 178, 238, 0, & + 43, 92, 192, 201, 0, & + 54, 79, 193, 232, 0, & + 53, 130, 156, 239, 0, & + 7, 85, 170, 240, 0, & + 55, 84, 109, 223, 0, & + 47, 171, 201, 215, 0, & + 9, 50, 149, 198, 212, & + 39, 90, 178, 213, 0, & + 25, 94, 169, 190, 0, & + 29, 179, 203, 221, 0, & + 8, 138, 202, 214, 0, & + 17, 79, 187, 235, 0, & + 49, 59, 77, 146, 205, & + 14, 75, 157, 235, 0, & + 42, 63, 155, 161, 224, & + 52, 158, 160, 218, 0, & + 45, 89, 140, 199, 0, & + 56, 95, 147, 220, 0, & + 57, 69, 97, 180, 187, & + 55, 86, 211, 238, 0, & + 2, 9, 57, 125, 184, & + 36, 76, 202, 215, 0, & + 53, 161, 166, 211, 0, & + 20, 67, 158, 193, 204, & + 12, 111, 116, 228, 0, & + 30, 89, 152, 233, 0, & + 1, 58, 134, 145, 0, & + 13, 86, 137, 226, 0, & + 44, 72, 105, 186, 220, & + 32, 106, 163, 239, 0, & + 3, 33, 80, 183, 0, & + 14, 120, 189, 202, 0, & + 59, 104, 176, 225, 0, & + 60, 110, 133, 236, 0, & + 48, 63, 87, 170, 204, & + 22, 61, 115, 171, 183, & + 19, 119, 132, 239, 0, & + 28, 88, 144, 173, 0, & + 186, 203, 205, 238, 0, & + 51, 91, 123, 211, 0, & + 32, 94, 157, 209, 0, & + 11, 58, 124, 203, 237, & + 61, 65, 122, 174, 206, & + 54, 98, 189, 217, 0, & + 47, 132, 198, 226, 0, & + 57, 81, 165, 233, 0, & + 40, 60, 134, 184, 206, & + 54, 167, 168, 240, 0, & + 3, 24, 62, 102, 177/ + +data nrw/ & +5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4, & +4,4,4,5,4,4,4,4,5,5,4,4,4,5,5,4,5,4,5,5, & +4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4, & +5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, & +4,5,4,4,4,4,4,4,5,4,5,5,5,4,5,4,4,4,5,4, & +5,4,4,5,5,5,4,4,5,4,5,4,5,4,4,4,4,4,4,4, & +4,4,4,5,4,4,4,4,4,5,4,5,4,4,4,5,4,5,4,4, & +5,4,4,4,4,5,4,4,4,4,4,5,5,4,4,4,4,4,5,5, & +4,4,4,5,4,5/ + +ncw=3 + diff --git a/lib/fst240/ldpcsim240_74.f90 b/lib/fst240/ldpcsim240_74.f90 new file mode 100644 index 000000000..743dff34b --- /dev/null +++ b/lib/fst240/ldpcsim240_74.f90 @@ -0,0 +1,125 @@ +program ldpcsim240_74 + +! End-to-end test of the (240,74)/crc24 encoder and decoders. + + use packjt77 + + parameter(N=240, K=74, M=N-K) + character*8 arg + character*37 msg0,msg + character*77 c77 + character*24 c24 + integer*1 msgbits(74) + integer*1 apmask(240) + integer*1 cw(240) + integer*1 codeword(N),message74(74) + integer ncrc24 + real rxdata(N),llr(N) + logical first,unpk77_success + data first/.true./ + + nargs=iargc() + if(nargs.ne.5 .and. nargs.ne.6) then + print*,'Usage: ldpcsim niter ndeep #trials s K [msg]' + print*,'e.g. ldpcsim240_74 20 5 1000 0.85 64 "K9AN K1JT FN20"' + print*,'s : if negative, then value is ignored and sigma is calculated from SNR.' + print*,'niter: is the number of BP iterations.' + print*,'ndeep: -1 is BP only, ndeep>=0 is OSD order' + print*,'K :is the number of message+CRC bits and must be in the range [50,74]' + print*,'WSPR-format message is optional' + return + endif + call getarg(1,arg) + read(arg,*) max_iterations + call getarg(2,arg) + read(arg,*) norder + call getarg(3,arg) + read(arg,*) ntrials + call getarg(4,arg) + read(arg,*) s + call getarg(5,arg) + read(arg,*) Keff + msg0='K9AN K1JT FN20 ' + if(nargs.eq.6) call getarg(6,msg0) + call pack77(msg0,i3,n3,c77) + + rate=real(Keff)/real(N) + + write(*,*) "code rate: ",rate + write(*,*) "niter : ",max_iterations + write(*,*) "norder : ",norder + write(*,*) "s : ",s + write(*,*) "K : ",Keff + + msgbits=0 + read(c77,'(77i1)') msgbits(1:77) + write(*,*) 'message' + write(*,'(77i1)') msgbits(1:77) + + call get_crc24(msgbits,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(51:74) +write(*,'(24i1)') msgbits(51:74) + write(*,*) 'message with crc24' + write(*,'(74i1)') msgbits(1:74) + call encode240_74(msgbits,codeword) + call init_random_seed() + call sgran() + + write(*,*) 'codeword' + write(*,'(77i1,1x,24i1,1x,73i1)') codeword + + write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate" + do idb = 8,-3,-1 + db=idb/2.0-1.0 + sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No +! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No + ngood=0 + nue=0 + nberr=0 + do itrial=1, ntrials +! Create a realization of a noisy received word + do i=1,N + rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran() + enddo + nerr=0 + do i=1,N + if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1 + enddo + nberr=nberr+nerr + + rxav=sum(rxdata)/N + rx2av=sum(rxdata*rxdata)/N + rxsig=sqrt(rx2av-rxav*rxav) + rxdata=rxdata/rxsig + if( s .lt. 0 ) then + ss=sigma + else + ss=s + endif + + llr=2.0*rxdata/(ss*ss) + apmask=0 + dmin=0.0 + maxosd=2 + call decode240_74(llr, Keff, maxosd, norder, apmask, message74, cw, ntype, nharderror, dmin) + if(nharderror.ge.0) then + n2err=0 + do i=1,N + if( cw(i).ne.codeword(i) ) n2err=n2err+1 + enddo + if(n2err.eq.0) then + ngood=ngood+1 + else + nue=nue+1 + endif + endif + enddo +! snr2500=db+10*log10(200.0/116.0/2500.0) + esn0=db+10*log10(rate) + pberr=real(nberr)/(real(ntrials*N)) + write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr + + enddo + +end program ldpcsim240_74 diff --git a/lib/fst240/osd240_74.f90 b/lib/fst240/osd240_74.f90 new file mode 100644 index 000000000..a44b69867 --- /dev/null +++ b/lib/fst240/osd240_74.f90 @@ -0,0 +1,403 @@ +subroutine osd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin) +! +! An ordered-statistics decoder for the (240,74) code. +! Message payload is 50 bits. Any or all of a 24-bit CRC can be +! used for detecting incorrect codewords. The remaining CRC bits are +! cascaded with the LDPC code for the purpose of improving the +! distance spectrum of the code. +! +! If p1 (0.le.p1.le.24) is the number of CRC24 bits that are +! to be used for bad codeword detection, then the argument k should +! be set to 77+p1. +! +! Valid values for k are in the range [50,74]. +! + character*24 c24 + integer, parameter:: N=240 + integer*1 apmask(N),apmaskr(N) + integer*1, allocatable, save :: gen(:,:) + integer*1, allocatable :: genmrb(:,:),g2(:,:) + integer*1, allocatable :: temp(:),m0(:),me(:),mi(:),misub(:),e2sub(:),e2(:),ui(:) + integer*1, allocatable :: r2pat(:) + integer indices(N),nxor(N) + integer*1 cw(N),ce(N),c0(N),hdec(N) + integer*1, allocatable :: decoded(:) + integer*1 message74(74) + integer indx(N) + real llr(N),rx(N),absrx(N) + + logical first,reset + data first/.true./ + save first + + allocate( genmrb(k,N), g2(N,k) ) + allocate( temp(k), m0(k), me(k), mi(k), misub(k), e2sub(N-k), e2(N-k), ui(N-k) ) + allocate( r2pat(N-k), decoded(k) ) + + if( first ) then ! fill the generator matrix +! +! Create generator matrix for partial CRC cascaded with LDPC code. +! +! Let p2=74-k and p1+p2=24. +! +! The last p2 bits of the CRC24 are cascaded with the LDPC code. +! +! The first p1=k-50 CRC24 bits will be used for error detection. +! + allocate( gen(k,N) ) + gen=0 + do i=1,k + message74=0 + message74(i)=1 + if(i.le.50) then + call get_crc24(message74,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') message74(51:74) + message74(51:k)=0 + endif + call encode240_74(message74,cw) + gen(i,:)=cw + enddo + + first=.false. + endif + + rx=llr + apmaskr=apmask + +! Hard decisions on the received word. + hdec=0 + where(rx .ge. 0) hdec=1 + +! Use magnitude of received symbols as a measure of reliability. + absrx=abs(rx) + call indexx(absrx,N,indx) + +! Re-order the columns of the generator matrix in order of decreasing reliability. + do i=1,N + genmrb(1:k,i)=gen(1:k,indx(N+1-i)) + indices(i)=indx(N+1-i) + enddo + +! Do gaussian elimination to create a generator matrix with the most reliable +! received bits in positions 1:k in order of decreasing reliability (more or less). + do id=1,k ! diagonal element indices + do icol=id,k+20 ! The 20 is ad hoc - beware + iflag=0 + if( genmrb(id,icol) .eq. 1 ) then + iflag=1 + if( icol .ne. id ) then ! reorder column + temp(1:k)=genmrb(1:k,id) + genmrb(1:k,id)=genmrb(1:k,icol) + genmrb(1:k,icol)=temp(1:k) + itmp=indices(id) + indices(id)=indices(icol) + indices(icol)=itmp + endif + do ii=1,k + if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then + genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) + endif + enddo + exit + endif + enddo + enddo + + g2=transpose(genmrb) + +! The hard decisions for the k MRB bits define the order 0 message, m0. +! Encode m0 using the modified generator matrix to find the "order 0" codeword. +! Flip various combinations of bits in m0 and re-encode to generate a list of +! codewords. Return the member of the list that has the smallest Euclidean +! distance to the received word. + + hdec=hdec(indices) ! hard decisions from received symbols + m0=hdec(1:k) ! zero'th order message + absrx=absrx(indices) + rx=rx(indices) + apmaskr=apmaskr(indices) + + call mrbencode74(m0,c0,g2,N,k) + nxor=ieor(c0,hdec) + nhardmin=sum(nxor) + dmin=sum(nxor*absrx) + + cw=c0 + ntotal=0 + nrejected=0 + npre1=0 + npre2=0 + + if(ndeep.eq.0) goto 998 ! norder=0 + if(ndeep.gt.6) ndeep=6 + if( ndeep.eq. 1) then + nord=1 + npre1=0 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.2) then + nord=1 + npre1=1 + npre2=0 + nt=40 + ntheta=12 + elseif(ndeep.eq.3) then + nord=1 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=14 + elseif(ndeep.eq.4) then + nord=2 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=17 + elseif(ndeep.eq.5) then + nord=3 + npre1=1 + npre2=1 + nt=40 + ntheta=12 + ntau=15 + elseif(ndeep.eq.6) then + nord=4 + npre1=1 + npre2=1 + nt=95 + ntheta=12 + ntau=15 + endif + + do iorder=1,nord + misub(1:k-iorder)=0 + misub(k-iorder+1:k)=1 + iflag=k-iorder+1 + do while(iflag .ge.0) + if(iorder.eq.nord .and. npre1.eq.0) then + iend=iflag + else + iend=1 + endif + d1=0. + do n1=iflag,iend,-1 + mi=misub + mi(n1)=1 + if(any(iand(apmaskr(1:k),mi).eq.1)) cycle + ntotal=ntotal+1 + me=ieor(m0,mi) + if(n1.eq.iflag) then + call mrbencode74(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + e2=e2sub + nd1kpt=sum(e2sub(1:nt))+1 + d1=sum(ieor(me(1:k),hdec(1:k))*absrx(1:k)) + else + e2=ieor(e2sub,g2(k+1:N,n1)) + nd1kpt=sum(e2(1:nt))+2 + endif + if(nd1kpt .le. ntheta) then + call mrbencode74(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + if(n1.eq.iflag) then + dd=d1+sum(e2sub*absrx(k+1:N)) + else + dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(k+1:N)) + endif + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + nd1kptbest=nd1kpt + endif + else + nrejected=nrejected+1 + endif + enddo +! Get the next test error pattern, iflag will go negative +! when the last pattern with weight iorder has been generated. + call nextpat74(misub,k,iorder,iflag) + enddo + enddo + + if(npre2.eq.1) then + reset=.true. + ntotal=0 + do i1=k,1,-1 + do i2=i1-1,1,-1 + ntotal=ntotal+1 + mi(1:ntau)=ieor(g2(k+1:k+ntau,i1),g2(k+1:k+ntau,i2)) + call boxit74(reset,mi(1:ntau),ntau,ntotal,i1,i2) + enddo + enddo + + ncount2=0 + ntotal2=0 + reset=.true. +! Now run through again and do the second pre-processing rule + misub(1:k-nord)=0 + misub(k-nord+1:k)=1 + iflag=k-nord+1 + do while(iflag .ge.0) + me=ieor(m0,misub) + call mrbencode74(me,ce,g2,N,k) + e2sub=ieor(ce(k+1:N),hdec(k+1:N)) + do i2=0,ntau + ntotal2=ntotal2+1 + ui=0 + if(i2.gt.0) ui(i2)=1 + r2pat=ieor(e2sub,ui) +778 continue + call fetchit74(reset,r2pat(1:ntau),ntau,in1,in2) + if(in1.gt.0.and.in2.gt.0) then + ncount2=ncount2+1 + mi=misub + mi(in1)=1 + mi(in2)=1 + if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:k),mi).eq.1)) cycle + me=ieor(m0,mi) + call mrbencode74(me,ce,g2,N,k) + nxor=ieor(ce,hdec) + dd=sum(nxor*absrx) + if( dd .lt. dmin ) then + dmin=dd + cw=ce + nhardmin=sum(nxor) + endif + goto 778 + endif + enddo + call nextpat74(misub,k,nord,iflag) + enddo + endif + +998 continue +! Re-order the codeword to [message bits][parity bits] format. + cw(indices)=cw + hdec(indices)=hdec + message74=cw(1:74) + call get_crc24(message74,74,nbadcrc) + if(nbadcrc.ne.0) nhardmin=-nhardmin + + return +end subroutine osd240_74 + +subroutine mrbencode74(me,codeword,g2,N,K) + integer*1 me(K),codeword(N),g2(N,K) +! fast encoding for low-weight test patterns + codeword=0 + do i=1,K + if( me(i) .eq. 1 ) then + codeword=ieor(codeword,g2(1:N,i)) + endif + enddo + return +end subroutine mrbencode74 + +subroutine nextpat74(mi,k,iorder,iflag) + integer*1 mi(k),ms(k) +! generate the next test error pattern + ind=-1 + do i=1,k-1 + if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i + enddo + if( ind .lt. 0 ) then ! no more patterns of this order + iflag=ind + return + endif + ms=0 + ms(1:ind-1)=mi(1:ind-1) + ms(ind)=1 + ms(ind+1)=0 + if( ind+1 .lt. k ) then + nz=iorder-sum(ms) + ms(k-nz+1:k)=1 + endif + mi=ms + do i=1,k ! iflag will point to the lowest-index 1 in mi + if(mi(i).eq.1) then + iflag=i + exit + endif + enddo + return +end subroutine nextpat74 + +subroutine boxit74(reset,e2,ntau,npindex,i1,i2) + integer*1 e2(1:ntau) + integer indexes(5000,2),fp(0:525000),np(5000) + logical reset + common/boxes/indexes,fp,np + + if(reset) then + patterns=-1 + fp=-1 + np=-1 + sc=-1 + indexes=-1 + reset=.false. + endif + + indexes(npindex,1)=i1 + indexes(npindex,2)=i2 + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + + ip=fp(ipat) ! see what's currently stored in fp(ipat) + if(ip.eq.-1) then + fp(ipat)=npindex + else + do while (np(ip).ne.-1) + ip=np(ip) + enddo + np(ip)=npindex + endif + return +end subroutine boxit74 + +subroutine fetchit74(reset,e2,ntau,i1,i2) + integer indexes(5000,2),fp(0:525000),np(5000) + integer lastpat + integer*1 e2(ntau) + logical reset + common/boxes/indexes,fp,np + save lastpat,inext + + if(reset) then + lastpat=-1 + reset=.false. + endif + + ipat=0 + do i=1,ntau + if(e2(i).eq.1) then + ipat=ipat+ishft(1,ntau-i) + endif + enddo + index=fp(ipat) + + if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices + i1=indexes(index,1) + i2=indexes(index,2) + inext=np(index) + elseif(lastpat.eq.ipat .and. inext.gt.0) then + i1=indexes(inext,1) + i2=indexes(inext,2) + inext=np(inext) + else + i1=-1 + i2=-1 + inext=-1 + endif + lastpat=ipat + return +end subroutine fetchit74 + diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 85038769f..745f2c68e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -154,7 +154,7 @@ contains hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return Keff=91 - iwspr=0 + iwspr=1 nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then @@ -413,6 +413,11 @@ contains if(ndepth.eq.1) ntmax=nblock apmask=0 + if(iwspr.eq.1) then + nblock=4 + ntmax=nblock + endif + do itry=1,ntmax if(itry.eq.1) llr=llra if(itry.eq.2.and.itry.le.nblock) llr=llrb @@ -471,8 +476,10 @@ contains else maxosd=2 call timer('d240_74 ',0) -! call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & -! ntype,nharderrors,dmin) + Keff=64 + norder=4 + call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & + ntype,nharderrors,dmin) call timer('d240_74 ',1) endif if(nharderrors .ge.0) then @@ -694,7 +701,8 @@ write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & enddo call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) s2=s2/base !Normalize wrt noise level - thresh=1.25 !First candidate threshold +! thresh=1.25 + thresh=1.15 !First candidate threshold ncand=0 candidates=0 From d7448347e5be78710f18e739caaf64ad38df117e Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 30 Jun 2020 15:11:36 -0400 Subject: [PATCH 100/239] Install a basic framework for handling FST240W decodes. --- lib/decoder.f90 | 9 ++++++--- lib/fst240_decode.f90 | 13 +++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 0266dc2a6..261591f3f 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -194,12 +194,13 @@ subroutine multimode_decoder(ss,id2,params,nfsample) params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,params%ndepth,params%ntr,params%nexp_decode, & params%ntol,params%nzhsym,params%emedelay, & - logical(params%lapcqonly),params%napwid,mycall,hiscall) + logical(params%lapcqonly),params%napwid,mycall,hiscall, & + params%nfsplit,iwspr) call timer('dec240 ',1) go to 800 endif - rms=sqrt(dot_product(float(id2(300000:310000)), & + rms=sqrt(dot_product(float(id2(300000:310000)), & float(id2(300000:310000)))/10000.0) if(rms.lt.2.0) go to 800 @@ -681,7 +682,7 @@ contains end subroutine ft4_decoded subroutine fst240_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & - qual,ntrperiod) + qual,ntrperiod,lwspr) use fst240_decode implicit none @@ -696,6 +697,8 @@ contains integer, intent(in) :: nap real, intent(in) :: qual integer, intent(in) :: ntrperiod + logical, intent(in) :: lwspr + character*2 annot character*37 decoded0 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 5c5d07838..232912ca0 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -8,7 +8,7 @@ module fst240_decode abstract interface subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & - decoded,nap,qual,ntrperiod) + decoded,nap,qual,ntrperiod,lwspr) import fst240_decoder implicit none class(fst240_decoder), intent(inout) :: this @@ -21,6 +21,7 @@ module fst240_decode integer, intent(in) :: nap real, intent(in) :: qual integer, intent(in) :: ntrperiod + logical, intent(in) :: lwspr end subroutine fst240_decode_callback end interface @@ -28,7 +29,7 @@ contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol,nzhsym, & - emedelay,lapcqonly,napwid,mycall,hiscall) + emedelay,lapcqonly,napwid,mycall,hiscall,nfsplit,iwspr) use timer_module, only: timer use packjt77 @@ -62,7 +63,7 @@ contains integer mcq(29),mrrr(19),m73(19),mrr73(19) logical badsync,unpk77_success,single_decode - logical first,nohiscall + logical first,nohiscall,lwspr integer*2 iwave(300*12000) @@ -503,10 +504,10 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud -write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & - nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg +!write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & +! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,x!dt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual,ntrperiod) + iaptype,qual,ntrperiod,lwspr) goto 2002 else cycle From 630ef640ac2bf801fee078b07c476416d6af2d45 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 15:06:18 -0500 Subject: [PATCH 101/239] First cut at joint QSO/WSPR type decoding for FST240. --- lib/fst240_decode.f90 | 1319 +++++++++++++++++++++-------------------- 1 file changed, 671 insertions(+), 648 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f899f544c..c82c18e14 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -1,99 +1,100 @@ module fst240_decode - type :: fst240_decoder - procedure(fst240_decode_callback), pointer :: callback + type :: fst240_decoder + procedure(fst240_decode_callback), pointer :: callback contains - procedure :: decode - end type fst240_decoder + procedure :: decode + end type fst240_decoder - abstract interface - subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & - decoded,nap,qual,ntrperiod,lwspr) - import fst240_decoder - implicit none - class(fst240_decoder), intent(inout) :: this - integer, intent(in) :: nutc - real, intent(in) :: sync - integer, intent(in) :: nsnr - real, intent(in) :: dt - real, intent(in) :: freq - character(len=37), intent(in) :: decoded - integer, intent(in) :: nap - real, intent(in) :: qual - integer, intent(in) :: ntrperiod - logical, intent(in) :: lwspr - end subroutine fst240_decode_callback - end interface + abstract interface + subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & + decoded,nap,qual,ntrperiod,lwspr) + import fst240_decoder + implicit none + class(fst240_decoder), intent(inout) :: this + integer, intent(in) :: nutc + real, intent(in) :: sync + integer, intent(in) :: nsnr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + integer, intent(in) :: ntrperiod + logical, intent(in) :: lwspr + end subroutine fst240_decode_callback + end interface contains - subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & + subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol,nzhsym, & emedelay,lapcqonly,napwid,mycall,hiscall,nfsplit,iwspr) - use timer_module, only: timer - use packjt77 - include 'fst240/fst240_params.f90' - parameter (MAXCAND=100) - class(fst240_decoder), intent(inout) :: this - procedure(fst240_decode_callback) :: callback - character*37 decodes(100) - character*37 msg,msgsent - character*77 c77 - character*12 mycall,hiscall - character*12 mycall0,hiscall0 - complex, allocatable :: c2(:) - complex, allocatable :: cframe(:) - complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable :: r_data(:) - real llr(240),llra(240),llrb(240),llrc(240),llrd(240) - real candidates(100,4) - real bitmetrics(320,4) - real s4(0:3,NN) - logical lapcqonly - integer itone(NN) - integer hmod - integer*1 apmask(240),cw(240) - integer*1 hbits(320) - integer*1 message101(101),message74(74),message77(77) - integer*1 rvec(77) - integer apbits(240) - integer nappasses(0:5) ! # of decoding passes for QSO states 0-5 - integer naptypes(0:5,4) ! (nQSOProgress,decoding pass) - integer mcq(29),mrrr(19),m73(19),mrr73(19) + use timer_module, only: timer + use packjt77 + include 'fst240/fst240_params.f90' + parameter (MAXCAND=100) + class(fst240_decoder), intent(inout) :: this + procedure(fst240_decode_callback) :: callback + character*37 decodes(100) + character*37 msg,msgsent + character*77 c77 + character*12 mycall,hiscall + character*12 mycall0,hiscall0 + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real llr(240),llra(240),llrb(240),llrc(240),llrd(240) + real candidates(100,4) + real bitmetrics(320,4) + real s4(0:3,NN) + real minsync + logical lapcqonly + integer itone(NN) + integer hmod + integer*1 apmask(240),cw(240) + integer*1 hbits(320) + integer*1 message101(101),message74(74),message77(77) + integer*1 rvec(77) + integer apbits(240) + integer nappasses(0:5) ! # of decoding passes for QSO states 0-5 + integer naptypes(0:5,4) ! (nQSOProgress,decoding pass) + integer mcq(29),mrrr(19),m73(19),mrr73(19) - logical badsync,unpk77_success,single_decode - logical first,nohiscall,lwspr + logical badsync,unpk77_success,single_decode + logical first,nohiscall,lwspr - integer*2 iwave(300*12000) + integer*2 iwave(300*12000) - data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ - data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ - data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ - data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 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/ - data first/.true./ - save first,apbits,nappasses,naptypes,mycall0,hiscall0 + data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ + data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ + data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ + data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ + data first/.true./ + save first,apbits,nappasses,naptypes,mycall0,hiscall0 - this%callback => callback + this%callback => callback - dxcall13=hiscall ! initialize for use in packjt77 - mycall13=mycall + dxcall13=hiscall ! initialize for use in packjt77 + mycall13=mycall - if(first) then - mcq=2*mod(mcq+rvec(1:29),2)-1 - 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 + if(first) then + mcq=2*mod(mcq+rvec(1:29),2)-1 + 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 - nappasses(0)=2 - nappasses(1)=2 - nappasses(2)=2 - nappasses(3)=2 - nappasses(4)=2 - nappasses(5)=3 + nappasses(0)=2 + nappasses(1)=2 + nappasses(2)=2 + nappasses(3)=2 + nappasses(4)=2 + nappasses(5)=3 ! iaptype !------------------------ @@ -105,632 +106,654 @@ contains ! 6 MyCall DxCall RR73 (77 ap bits) !******** - naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) - naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 - naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 - naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 - naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 - naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 + naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) + naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 + naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 + naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 + naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 + naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 - mycall0='' - hiscall0='' - first=.false. - endif - - l1=index(mycall,char(0)) - if(l1.ne.0) mycall(l1:)=" " - l1=index(hiscall,char(0)) - if(l1.ne.0) hiscall(l1:)=" " - if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then - apbits=0 - apbits(1)=99 - apbits(30)=99 - - if(len(trim(mycall)) .lt. 3) go to 10 - - nohiscall=.false. - hiscall0=hiscall - if(len(trim(hiscall0)).lt.3) then - hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. - nohiscall=.true. + mycall0='' + hiscall0='' + first=.false. endif - msg=trim(mycall)//' '//trim(hiscall0)//' RR73' - i3=-1 - n3=-1 - call pack77(msg,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 - read(c77,'(77i1)') message77 - message77=mod(message77+rvec,2) - call encode174_91(message77,cw) - apbits=2*cw-1 - if(nohiscall) apbits(30)=99 -10 continue - mycall0=mycall - hiscall0=hiscall - endif + l1=index(mycall,char(0)) + if(l1.ne.0) mycall(l1:)=" " + l1=index(hiscall,char(0)) + if(l1.ne.0) hiscall(l1:)=" " + if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then + apbits=0 + apbits(1)=99 + apbits(30)=99 + + if(len(trim(mycall)) .lt. 3) go to 10 + + nohiscall=.false. + hiscall0=hiscall + if(len(trim(hiscall0)).lt.3) then + hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. + nohiscall=.true. + endif + msg=trim(mycall)//' '//trim(hiscall0)//' RR73' + i3=-1 + n3=-1 + call pack77(msg,i3,n3,c77) + call unpack77(c77,1,msgsent,unpk77_success) + if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 + read(c77,'(77i1)') message77 + message77=mod(message77+rvec,2) + call encode174_91(message77,cw) + apbits=2*cw-1 + if(nohiscall) apbits(30)=99 + +10 continue + mycall0=mycall + hiscall0=hiscall + endif !************************************ - hmod=2**nsubmode - if(nfqso+nqsoprogress.eq.-999) return - Keff=91 - iwspr=1 - nmax=15*12000 - single_decode=iand(nexp_decode,32).eq.32 - if(ntrperiod.eq.15) then - nsps=720 + hmod=2**nsubmode + if(nfqso+nqsoprogress.eq.-999) return + Keff=91 + iwspr=1 nmax=15*12000 - ndown=18/hmod !nss=40,80,160,400 - if(hmod.eq.4) ndown=4 - if(hmod.eq.8) ndown=2 - nfft1=int(nmax/ndown)*ndown - else if(ntrperiod.eq.30) then - nsps=1680 - nmax=30*12000 - ndown=42/hmod !nss=40,80,168,336 - nfft1=359856 - if(hmod.eq.4) then - ndown=10 - nfft1=nmax + single_decode=iand(nexp_decode,32).eq.32 + if(ntrperiod.eq.15) then + nsps=720 + nmax=15*12000 + ndown=18/hmod !nss=40,80,160,400 + if(hmod.eq.4) ndown=4 + if(hmod.eq.8) ndown=2 + nfft1=int(nmax/ndown)*ndown + else if(ntrperiod.eq.30) then + nsps=1680 + nmax=30*12000 + ndown=42/hmod !nss=40,80,168,336 + nfft1=359856 + if(hmod.eq.4) then + ndown=10 + nfft1=nmax + endif + if(hmod.eq.8) then + ndown=5 + nfft1=nmax + endif + else if(ntrperiod.eq.60) then + nsps=3888 + nmax=60*12000 + ndown=96/hmod !nss=36,81,162,324 + if(hmod.eq.1) ndown=108 + nfft1=int(719808/ndown)*ndown + else if(ntrperiod.eq.120) then + nsps=8200 + nmax=120*12000 + ndown=200/hmod !nss=40,82,164,328 + if(hmod.eq.1) ndown=205 + nfft1=int(nmax/ndown)*ndown + else if(ntrperiod.eq.300) then + nsps=21504 + nmax=300*12000 + ndown=512/hmod !nss=42,84,168,336 + nfft1=int((nmax-200)/ndown)*ndown + end if + nss=nsps/ndown + fs=12000.0 !Sample rate + fs2=fs/ndown + nspsec=nint(fs2) + dt=1.0/fs !Sample interval (s) + dt2=1.0/fs2 + tt=nsps*dt !Duration of "itone" symbols (s) + baud=1.0/tt + sigbw=4.0*hmod*baud + nfft2=nfft1/ndown !make sure that nfft1 is exactly nfft2*ndown + nfft1=nfft2*ndown + nh1=nfft1/2 + + allocate( r_data(1:nfft1+2) ) + allocate( c_bigfft(0:nfft1/2) ) + + allocate( c2(0:nfft2-1) ) + allocate( cframe(0:160*nss-1) ) + + + if(ndeep.eq.3) then + nblock=1 + if(hmod.eq.1) nblock=4 ! number of block sizes to try + jittermax=2 + norder=3 + elseif(ndeep.eq.2) then + nblock=1 + if(hmod.eq.1) nblock=3 + jittermax=0 + norder=3 + elseif(ndeep.eq.1) then + nblock=1 + jittermax=0 + norder=3 endif - if(hmod.eq.8) then - ndown=5 - nfft1=nmax - endif - else if(ntrperiod.eq.60) then - nsps=3888 - nmax=60*12000 - ndown=96/hmod !nss=36,81,162,324 - if(hmod.eq.1) ndown=108 - nfft1=int(719808/ndown)*ndown - else if(ntrperiod.eq.120) then - nsps=8200 - nmax=120*12000 - ndown=200/hmod !nss=40,82,164,328 - if(hmod.eq.1) ndown=205 - nfft1=int(nmax/ndown)*ndown - else if(ntrperiod.eq.300) then - nsps=21504 - nmax=300*12000 - ndown=512/hmod !nss=42,84,168,336 - nfft1=int((nmax-200)/ndown)*ndown - end if - nss=nsps/ndown - fs=12000.0 !Sample rate - fs2=fs/ndown - nspsec=nint(fs2) - dt=1.0/fs !Sample interval (s) - dt2=1.0/fs2 - tt=nsps*dt !Duration of "itone" symbols (s) - baud=1.0/tt - sigbw=4.0*hmod*baud - nfft2=nfft1/ndown !make sure that nfft1 is exactly nfft2*ndown - nfft1=nfft2*ndown - nh1=nfft1/2 - allocate( r_data(1:nfft1+2) ) - allocate( c_bigfft(0:nfft1/2) ) - - allocate( c2(0:nfft2-1) ) - allocate( cframe(0:160*nss-1) ) - - if(single_decode) then - fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) - fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) - else - fa=max(100,nfa) - fb=min(4800,nfb) - endif - - if(ndeep.eq.3) then - nblock=1 - if(hmod.eq.1) nblock=4 ! number of block sizes to try - jittermax=2 - norder=3 - elseif(ndeep.eq.2) then - nblock=1 - if(hmod.eq.1) nblock=3 - jittermax=0 - norder=3 - elseif(ndeep.eq.1) then - nblock=1 - jittermax=0 - norder=3 - endif - -! The big fft is done once and is used for calculating the smoothed spectrum +! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. - r_data(1:nfft1)=iwave(1:nfft1) - r_data(nfft1+1:nfft1+2)=0.0 - call four2a(r_data,nfft1,1,-1,0) - c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + r_data(1:nfft1)=iwave(1:nfft1) + r_data(nfft1+1:nfft1+2)=0.0 + call four2a(r_data,nfft1,1,-1,0) + c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + + if(iwspr.eq.0) then + itype1=1 + itype2=1 + elseif( iwspr.eq.1 ) then + itype1=2 + itype2=2 + elseif( iwspr.eq.2 ) then + itype1=1 + itype2=2 + endif + + do iqorw=itype1,itype2 ! iqorw=1 for QSO mode and iqorw=2 for wspr-type messages + if( iwspr.lt.2 ) then + if( single_decode ) then + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) + else + fa=max(100,nfa) + fb=min(4800,nfb) + endif + elseif( iwspr.eq.2 .and. iqorw.eq.1 ) then + fa=max(100,nfa) + fb=nfsplit + elseif( iwspr.eq.2 .and. iqorw.eq.2 ) then + fa=nfsplit + fb=min(4800,nfb) + endif + + minsync=1.25 + if(iqorw.eq.2) then + minsync=1.2 + endif ! Get first approximation of candidate frequencies - call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates,base) + call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + minsync,ncand,candidates,base) - ndecodes=0 - decodes=' ' + ndecodes=0 + decodes=' ' - isbest1=0 - isbest8=0 - fc21=0. - fc28=0. - do icand=1,ncand - fc0=candidates(icand,1) - detmet=candidates(icand,2) + isbest1=0 + isbest8=0 + fc21=0. + fc28=0. + do icand=1,ncand + fc0=candidates(icand,1) + detmet=candidates(icand,2) ! Downconvert and downsample a slice of the spectrum centered on the ! rough estimate of the candidates frequency. ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown - call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) + call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) - call timer('sync240 ',0) - do isync=0,1 - if(isync.eq.0) then - fc1=0.0 - if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s - is0=1.5*nspsec - ishw=1.5*nspsec - else ! search plus or minus 1.5 s centered on emedelay - is0=nint(emedelay*nspsec) - ishw=1.5*nspsec - endif - isst=4*hmod - ifhw=12 - df=.1*baud - else if(isync.eq.1) then - fc1=fc21 - if(hmod.eq.1) fc1=fc28 - is0=isbest1 - if(hmod.eq.1) is0=isbest8 - ishw=4*hmod - isst=1*hmod - ifhw=7 - df=.02*baud - endif - - smax1=0.0 - smax8=0.0 - do if=-ifhw,ifhw - fc=fc1+df*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) - call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) - if(sync8.gt.smax8) then - fc28=fc - isbest8=istart - smax8=sync8 + call timer('sync240 ',0) + do isync=0,1 + if(isync.eq.0) then + fc1=0.0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint(emedelay*nspsec) + ishw=1.5*nspsec + endif + isst=4*hmod + ifhw=12 + df=.1*baud + else if(isync.eq.1) then + fc1=fc21 + if(hmod.eq.1) fc1=fc28 + is0=isbest1 + if(hmod.eq.1) is0=isbest8 + ishw=4*hmod + isst=1*hmod + ifhw=7 + df=.02*baud endif - if(sync1.gt.smax1) then - fc21=fc - isbest1=istart - smax1=sync1 + + smax1=0.0 + smax8=0.0 + do if=-ifhw,ifhw + fc=fc1+df*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) + call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) + if(sync8.gt.smax8) then + fc28=fc + isbest8=istart + smax8=sync8 + endif + if(sync1.gt.smax1) then + fc21=fc + isbest1=istart + smax1=sync1 + endif + enddo + enddo + enddo + call timer('sync240 ',1) + + if(smax8/smax1 .lt. 0.65 ) then + fc2=fc21 + isbest=isbest1 + njitter=2 + else + fc2=fc28 + isbest=isbest8 + njitter=2 + endif + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + candidates(icand,3)=fc_synced + candidates(icand,4)=isbest + enddo + +! remove duplicate candidates + do icand=1,ncand + fc=candidates(icand,3) + isbest=nint(candidates(icand,4)) + do ic2=1,ncand + fc2=candidates(ic2,3) + isbest2=nint(candidates(ic2,4)) + if(ic2.ne.icand .and. fc2.gt.0.0) then + if(abs(fc2-fc).lt.0.10*baud) then ! same frequency + if(abs(isbest2-isbest).le.2) then + candidates(ic2,3)=-1 + endif + endif endif enddo enddo - enddo - call timer('sync240 ',1) - if(smax8/smax1 .lt. 0.65 ) then - fc2=fc21 - isbest=isbest1 - njitter=2 - else - fc2=fc28 - isbest=isbest8 - njitter=2 - endif - fc_synced = fc0 + fc2 - dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 - candidates(icand,3)=fc_synced - candidates(icand,4)=isbest - enddo - -! remove duplicate candidates - do icand=1,ncand - fc=candidates(icand,3) - isbest=nint(candidates(icand,4)) - do ic2=1,ncand - fc2=candidates(ic2,3) - isbest2=nint(candidates(ic2,4)) - if(ic2.ne.icand .and. fc2.gt.0.0) then - if(abs(fc2-fc).lt.0.10*baud) then ! same frequency - if(abs(isbest2-isbest).le.2) then - candidates(ic2,3)=-1 - endif + ic=0 + do icand=1,ncand + if(candidates(icand,3).gt.0) then + ic=ic+1 + candidates(ic,:)=candidates(icand,:) endif - endif - enddo - enddo + enddo + ncand=ic + xsnr=0. - ic=0 - do icand=1,ncand - if(candidates(icand,3).gt.0) then - ic=ic+1 - candidates(ic,:)=candidates(icand,:) - endif - enddo - ncand=ic - xsnr=0. + do icand=1,ncand + sync=candidates(icand,2) + fc_synced=candidates(icand,3) + isbest=nint(candidates(icand,4)) + xdt=(isbest-nspsec)/fs2 + if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 + call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) - do icand=1,ncand - sync=candidates(icand,2) - fc_synced=candidates(icand,3) - isbest=nint(candidates(icand,4)) - xdt=(isbest-nspsec)/fs2 - if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 - call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) + do ijitter=0,jittermax + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+160*nss-1) + bitmetrics=0 + call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + if(badsync) cycle - do ijitter=0,jittermax - if(ijitter.eq.0) ioffset=0 - if(ijitter.eq.1) ioffset=1 - if(ijitter.eq.2) ioffset=-1 - is0=isbest+ioffset - if(is0.lt.0) cycle - cframe=c2(is0:is0+160*nss-1) - bitmetrics=0 - call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) - if(badsync) cycle + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5 + if(nsync_qual.lt. 44) cycle !### Value ?? ### - hbits=0 - where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 44) cycle !### Value ?? ### + scalefac=2.83 + llra( 1: 60)=bitmetrics( 17: 76, 1) + llra( 61:120)=bitmetrics( 93:152, 1) + llra(121:180)=bitmetrics(169:228, 1) + llra(181:240)=bitmetrics(245:304, 1) + llra=scalefac*llra + llrb( 1: 60)=bitmetrics( 17: 76, 2) + llrb( 61:120)=bitmetrics( 93:152, 2) + llrb(121:180)=bitmetrics(169:228, 2) + llrb(181:240)=bitmetrics(245:304, 2) + llrb=scalefac*llrb + llrc( 1: 60)=bitmetrics( 17: 76, 3) + llrc( 61:120)=bitmetrics( 93:152, 3) + llrc(121:180)=bitmetrics(169:228, 3) + llrc(181:240)=bitmetrics(245:304, 3) + llrc=scalefac*llrc + llrd( 1: 60)=bitmetrics( 17: 76, 4) + llrd( 61:120)=bitmetrics( 93:152, 4) + llrd(121:180)=bitmetrics(169:228, 4) + llrd(181:240)=bitmetrics(245:304, 4) + llrd=scalefac*llrd - scalefac=2.83 - llra( 1: 60)=bitmetrics( 17: 76, 1) - llra( 61:120)=bitmetrics( 93:152, 1) - llra(121:180)=bitmetrics(169:228, 1) - llra(181:240)=bitmetrics(245:304, 1) - llra=scalefac*llra - llrb( 1: 60)=bitmetrics( 17: 76, 2) - llrb( 61:120)=bitmetrics( 93:152, 2) - llrb(121:180)=bitmetrics(169:228, 2) - llrb(181:240)=bitmetrics(245:304, 2) - llrb=scalefac*llrb - llrc( 1: 60)=bitmetrics( 17: 76, 3) - llrc( 61:120)=bitmetrics( 93:152, 3) - llrc(121:180)=bitmetrics(169:228, 3) - llrc(181:240)=bitmetrics(245:304, 3) - llrc=scalefac*llrc - llrd( 1: 60)=bitmetrics( 17: 76, 4) - llrd( 61:120)=bitmetrics( 93:152, 4) - llrd(121:180)=bitmetrics(169:228, 4) - llrd(181:240)=bitmetrics(245:304, 4) - llrd=scalefac*llrd - - apmag=maxval(abs(llra))*1.1 - ntmax=nblock+nappasses(nQSOProgress) - if(lapcqonly) ntmax=nblock+1 - if(ndepth.eq.1) ntmax=nblock - apmask=0 - - if(iwspr.eq.1) then - nblock=4 - ntmax=nblock - endif - - do itry=1,ntmax - if(itry.eq.1) llr=llra - if(itry.eq.2.and.itry.le.nblock) llr=llrb - if(itry.eq.3.and.itry.le.nblock) llr=llrc - if(itry.eq.4.and.itry.le.nblock) llr=llrd - if(itry.le.nblock) then + apmag=maxval(abs(llra))*1.1 + ntmax=nblock+nappasses(nQSOProgress) + if(lapcqonly) ntmax=nblock+1 + if(ndepth.eq.1) ntmax=nblock apmask=0 - iaptype=0 - endif - napwid=1.2*(4.0*baud*hmod) - - if(itry.gt.nblock) then - if(nblock.eq.1) llr=llra - if(nblock.gt.1) llr=llrc - iaptype=naptypes(nQSOProgress,itry-nblock) - if(lapcqonly) iaptype=1 - if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall - if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - if(iaptype.eq.1) then ! CQ - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*mcq(1:29) - endif - - if(iaptype.eq.2) then ! MyCall ??? ??? - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*apbits(1:29) - endif - - if(iaptype.eq.3) then ! MyCall DxCall ??? - apmask=0 - apmask(1:58)=1 - llr(1:58)=apmag*apbits(1:58) + + if(iqorw.eq.2) then ! 50-bit msgs, no ap decoding + nblock=4 + ntmax=nblock endif - if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then - apmask=0 - apmask(1:77)=1 - llr(1:58)=apmag*apbits(1:58) - if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) - if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) - if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) - endif - endif - - dmin=0.0 - nharderrors=-1 - unpk77_success=.false. - if(iwspr.eq.0) then - maxosd=2 - call timer('d240_101',0) - call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & - cw,ntype,nharderrors,dmin) - call timer('d240_101',1) - else - maxosd=2 - call timer('d240_74 ',0) - Keff=64 - norder=4 - call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & - ntype,nharderrors,dmin) - call timer('d240_74 ',1) - endif - if(nharderrors .ge.0) then - if(iwspr.eq.0) then - write(c77,'(77i1)') mod(message101(1:77)+rvec,2) - call unpack77(c77,0,msg,unpk77_success) - else - write(c77,'(50i1)') message74(1:50) - c77(51:77)='000000000000000000000110000' - call unpack77(c77,0,msg,unpk77_success) - endif - if(unpk77_success) then - idupe=0 - do i=1,ndecodes - if(decodes(i).eq.msg) idupe=1 - enddo - if(idupe.eq.1) exit - ndecodes=ndecodes+1 - decodes(ndecodes)=msg - if(iwspr.eq.0) then - call get_fst240_tones_from_bits(message101,itone,iwspr) - xsig=0 - do i=1,NN - xsig=xsig+s4(itone(i),i)**2 - enddo - arg=400.0*(xsig/base)-1.0 - if(arg.gt.0.0) then - xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) - else - xsnr=-99.9 + do itry=1,ntmax + if(itry.eq.1) llr=llra + if(itry.eq.2.and.itry.le.nblock) llr=llrb + if(itry.eq.3.and.itry.le.nblock) llr=llrc + if(itry.eq.4.and.itry.le.nblock) llr=llrd + if(itry.le.nblock) then + apmask=0 + iaptype=0 + endif + napwid=1.2*(4.0*baud*hmod) + + if(itry.gt.nblock) then + if(nblock.eq.1) llr=llra + if(nblock.gt.1) llr=llrc + iaptype=naptypes(nQSOProgress,itry-nblock) + if(lapcqonly) iaptype=1 + if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall + if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall + if(iaptype.eq.1) then ! CQ + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*mcq(1:29) + endif + + if(iaptype.eq.2) then ! MyCall ??? ??? + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*apbits(1:29) + endif + + if(iaptype.eq.3) then ! MyCall DxCall ??? + apmask=0 + apmask(1:58)=1 + llr(1:58)=apmag*apbits(1:58) + endif + + if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then + apmask=0 + apmask(1:77)=1 + llr(1:58)=apmag*apbits(1:58) + if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) + if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) + if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) endif endif - nsnr=nint(xsnr) - qual=0. - fsig=fc_synced - 1.5*hmod*baud + + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iqorw.eq.1) then + maxosd=2 + norder=3 + call timer('d240_101',0) + call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & + cw,ntype,nharderrors,dmin) + call timer('d240_101',1) + elseif(iqorw.eq.2) then + maxosd=2 + call timer('d240_74 ',0) + Keff=64 + norder=4 + call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & + ntype,nharderrors,dmin) + call timer('d240_74 ',1) + endif + if(nharderrors .ge.0) then + if(iqor2.eq.1) then + write(c77,'(77i1)') mod(message101(1:77)+rvec,2) + call unpack77(c77,0,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,0,msg,unpk77_success) + endif + if(unpk77_success) then + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.msg) idupe=1 + enddo + if(idupe.eq.1) exit + ndecodes=ndecodes+1 + decodes(ndecodes)=msg + + call get_fst240_tones_from_bits(message101,itone,iwspr) + xsig=0 + do i=1,NN + xsig=xsig+s4(itone(i),i)**2 + enddo + arg=400.0*(xsig/base)-1.0 + if(arg.gt.0.0) then + xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) + else + xsnr=-99.9 + endif + endif + nsnr=nint(xsnr) + qual=0. + fsig=fc_synced - 1.5*hmod*baud !write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & ! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,x!dt,fsig,msg - call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual,ntrperiod,lwspr) - goto 2002 - else - cycle - endif - endif - enddo ! metrics - enddo ! istart jitter -2002 continue - enddo !candidate list!ws + call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & + iaptype,qual,ntrperiod,lwspr) + goto 2002 + endif + enddo ! metrics + enddo ! istart jitter +2002 continue + enddo !candidate list + enddo ! iqorw - return - end subroutine decode + return + end subroutine decode - subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) ! Compute sync power for a complex, downsampled FST240 signal. - include 'fst240/fst240_params.f90' - complex cd0(0:np-1) - complex, allocatable, save :: csync1(:),csync2(:) - complex, allocatable, save :: csynct1(:),csynct2(:) - complex ctwk(8*nss) - complex z1,z2,z3,z4,z5 - logical first - integer hmod,isyncword1(0:7),isyncword2(0:7) - real f0save - data isyncword1/0,1,3,2,1,0,2,3/ - data isyncword2/2,3,1,0,3,2,0,1/ - data first/.true./,f0save/-99.9/,nss0/-1/ - save first,twopi,dt,fac,f0save,nss0 - p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power + include 'fst240/fst240_params.f90' + complex cd0(0:np-1) + complex, allocatable, save :: csync1(:),csync2(:) + complex, allocatable, save :: csynct1(:),csynct2(:) + complex ctwk(8*nss) + complex z1,z2,z3,z4,z5 + logical first + integer hmod,isyncword1(0:7),isyncword2(0:7) + real f0save + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ + data first/.true./,f0save/-99.9/,nss0/-1/ + save first,twopi,dt,fac,f0save,nss0 + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power - if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) - if(first .or. nss.ne.nss0) then - allocate( csync1(8*nss), csync2(8*nss) ) - allocate( csynct1(8*nss), csynct2(8*nss) ) - twopi=8.0*atan(1.0) - dt=1/fs - k=1 - phi1=0.0 - phi2=0.0 - do i=0,7 - dphi1=twopi*hmod*(isyncword1(i)-1.5)/real(nss) - dphi2=twopi*hmod*(isyncword2(i)-1.5)/real(nss) - do j=1,nss - csync1(k)=cmplx(cos(phi1),sin(phi1)) - csync2(k)=cmplx(cos(phi2),sin(phi2)) - phi1=mod(phi1+dphi1,twopi) - phi2=mod(phi2+dphi2,twopi) - k=k+1 + if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) + if(first .or. nss.ne.nss0) then + allocate( csync1(8*nss), csync2(8*nss) ) + allocate( csynct1(8*nss), csynct2(8*nss) ) + twopi=8.0*atan(1.0) + dt=1/fs + k=1 + phi1=0.0 + phi2=0.0 + do i=0,7 + dphi1=twopi*hmod*(isyncword1(i)-1.5)/real(nss) + dphi2=twopi*hmod*(isyncword2(i)-1.5)/real(nss) + do j=1,nss + csync1(k)=cmplx(cos(phi1),sin(phi1)) + csync2(k)=cmplx(cos(phi2),sin(phi2)) + phi1=mod(phi1+dphi1,twopi) + phi2=mod(phi2+dphi2,twopi) + k=k+1 + enddo enddo - enddo - first=.false. - nss0=nss - fac=1.0/(8.0*nss) - endif - - if(f0.ne.f0save) then - dphi=twopi*f0*dt - phi=0.0 - do i=1,8*nss - ctwk(i)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dphi,twopi) - enddo - csynct1=ctwk*csync1 - csynct2=ctwk*csync2 - f0save=f0 - endif - - i1=i0 !Costas arrays - i2=i0+38*nss - i3=i0+76*nss - i4=i0+114*nss - i5=i0+152*nss - - s1=0.0 - s2=0.0 - s3=0.0 - s4=0.0 - s5=0.0 - - nsec=8/ncoh - do i=1,nsec - is=(i-1)*ncoh*nss - z1=0 - if(i1+is.ge.1) then - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + first=.false. + nss0=nss + fac=1.0/(8.0*nss) endif - z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) - z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z5=0 - if(i5+is+ncoh*nss-1.le.np) then - z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + + if(f0.ne.f0save) then + dphi=twopi*f0*dt + phi=0.0 + do i=1,8*nss + ctwk(i)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + enddo + csynct1=ctwk*csync1 + csynct2=ctwk*csync2 + f0save=f0 endif - s1=s1+abs(z1)/(8*nss) - s2=s2+abs(z2)/(8*nss) - s3=s3+abs(z3)/(8*nss) - s4=s4+abs(z4)/(8*nss) - s5=s5+abs(z5)/(8*nss) - enddo - sync = s1+s2+s3+s4+s5 - return - end subroutine sync_fst240 + i1=i0 !Costas arrays + i2=i0+38*nss + i3=i0+76*nss + i4=i0+114*nss + i5=i0+152*nss - subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) + s1=0.0 + s2=0.0 + s3=0.0 + s4=0.0 + s5=0.0 + + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=0 + if(i1+is.ge.1) then + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z5=0 + if(i5+is+ncoh*nss-1.le.np) then + z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + s4=s4+abs(z4)/(8*nss) + s5=s5+abs(z5)/(8*nss) + enddo + sync = s1+s2+s3+s4+s5 + + return + end subroutine sync_fst240 + + subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) ! Output: Complex data in c(), sampled at 12000/ndown Hz - complex c_bigfft(0:nfft1/2) - complex c1(0:nfft1/ndown-1) + complex c_bigfft(0:nfft1/2) + complex c1(0:nfft1/ndown-1) - df=12000.0/nfft1 - i0=nint(f0/df) - ih=nint( ( f0 + 1.3*sigbw/2.0 )/df) - nbw=ih-i0+1 - c1=0. - c1(0)=c_bigfft(i0) - nfft2=nfft1/ndown - do i=1,nbw - if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) - if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) - enddo - c1=c1/nfft2 - call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain - return - - end subroutine fst240_downsample - - subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates,base) - - complex c_bigfft(0:nfft1/2) !Full length FFT of raw data - integer hmod !Modulation index (submode) - integer im(1) !For maxloc - real candidates(100,4) !Candidate list - real s(18000) !Low resolution power spectrum - real s2(18000) !CCF of s() with 4 tones - real xdb(-3:3) !Model 4-tone CCF peaks - data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ - data nfft1z/-1/ - save nfft1z - - nh1=nfft1/2 - df1=fs/nfft1 - baud=fs/nsps !Keying rate - df2=baud/2.0 - nd=df2/df1 !s() sums this many bins of big FFT - ndh=nd/2 - ia=nint(max(100.0,fa)/df2) !Low frequency search limit - ib=nint(min(4800.0,fb)/df2) !High frequency limit - signal_bw=4*(12000.0/nsps)*hmod - analysis_bw=min(4800.0,fb)-max(100.0,fa) - noise_bw=10.0*signal_bw !Is this a good compromise? - if(analysis_bw.gt.noise_bw) then - ina=ia - inb=ib - else - fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, - fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw - fh = min(4800.0,fcenter+noise_bw/2.)/df2 - ina=nint(fl) - inb=nint(fh) - endif - - s=0. !Compute low-resloution power spectrum - do i=ina,inb ! noise analysis window includes signal analysis window - j0=nint(i*df2/df1) - do j=j0-ndh,j0+ndh - s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + df=12000.0/nfft1 + i0=nint(f0/df) + ih=nint( ( f0 + 1.3*sigbw/2.0 )/df) + nbw=ih-i0+1 + c1=0. + c1(0)=c_bigfft(i0) + nfft2=nfft1/ndown + do i=1,nbw + if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) + if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) enddo - enddo - - ina=max(ina,1+3*hmod) !Don't run off the ends - inb=min(inb,18000-3*hmod) - s2=0. - do i=ina,inb !Compute CCF of s() and 4 tones - s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) - enddo - call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) - s2=s2/base !Normalize wrt noise level -! thresh=1.25 - thresh=1.15 !First candidate threshold + c1=c1/nfft2 + call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain + return - ncand=0 - candidates=0 - if(ia.lt.3) ia=3 - if(ib.gt.18000-2) ib=18000-2 + end subroutine fst240_downsample + + subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + minsync,ncand,candidates,base) + + complex c_bigfft(0:nfft1/2) !Full length FFT of raw data + integer hmod !Modulation index (submode) + integer im(1) !For maxloc + real candidates(100,4) !Candidate list + real s(18000) !Low resolution power spectrum + real s2(18000) !CCF of s() with 4 tones + real xdb(-3:3) !Model 4-tone CCF peaks + real minsync + data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ + + nh1=nfft1/2 + df1=fs/nfft1 + baud=fs/nsps !Keying rate + df2=baud/2.0 + nd=df2/df1 !s() sums this many bins of big FFT + ndh=nd/2 + ia=nint(max(100.0,fa)/df2) !Low frequency search limit + ib=nint(min(4800.0,fb)/df2) !High frequency limit + signal_bw=4*(12000.0/nsps)*hmod + analysis_bw=min(4800.0,fb)-max(100.0,fa) + noise_bw=10.0*signal_bw !Is this a good compromise? + if(analysis_bw.gt.noise_bw) then + ina=ia + inb=ib + else + fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, + fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw + fh = min(4800.0,fcenter+noise_bw/2.)/df2 + ina=nint(fl) + inb=nint(fh) + endif + + s=0. !Compute low-resloution power spectrum + do i=ina,inb ! noise analysis window includes signal analysis window + j0=nint(i*df2/df1) + do j=j0-ndh,j0+ndh + s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + enddo + enddo + + ina=max(ina,1+3*hmod) !Don't run off the ends + inb=min(inb,18000-3*hmod) + s2=0. + do i=ina,inb !Compute CCF of s() and 4 tones + s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) + enddo + call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) + s2=s2/base !Normalize wrt noise level + + ncand=0 + candidates=0 + if(ia.lt.3) ia=3 + if(ib.gt.18000-2) ib=18000-2 ! Find candidates, using the CLEAN algorithm to remove a model of each one -! from s2() after it has been found. - pval=99.99 - do while(ncand.lt.100 .and. pval.gt.thresh) - im=maxloc(s2(ia:ib)) - iploc=ia+im(1)-1 !Index of CCF peak - pval=s2(iploc) !Peak value - if(s2(iploc).gt.thresh) then !Is this a possible candidate? - do i=-3,+3 !Remove 0.9 of a model CCF at - k=iploc+2*hmod*i !this frequency from s2() - if(k.ge.ia .and. k.le.ib) then - s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) - endif - enddo - ncand=ncand+1 - candidates(ncand,1)=df2*iploc !Candidate frequency - candidates(ncand,2)=pval !Rough estimate of SNR - endif - enddo +! from s2() after it has been found. + pval=99.99 + do while(ncand.lt.100 .and. pval.gt.minsync) + im=maxloc(s2(ia:ib)) + iploc=ia+im(1)-1 !Index of CCF peak + pval=s2(iploc) !Peak value + if(s2(iploc).gt.thresh) then !Is this a possible candidate? + do i=-3,+3 !Remove 0.9 of a model CCF at + k=iploc+2*hmod*i !this frequency from s2() + if(k.ge.ia .and. k.le.ib) then + s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) + endif + enddo + ncand=ncand+1 + candidates(ncand,1)=df2*iploc !Candidate frequency + candidates(ncand,2)=pval !Rough estimate of SNR + endif + enddo - return - end subroutine get_candidates_fst240 + return + end subroutine get_candidates_fst240 end module fst240_decode From 7345e1366154bb25b6bfe41c0ff79bd48b62c8c5 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 15:50:50 -0500 Subject: [PATCH 102/239] Fix a bug --- lib/fst240_decode.f90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index c82c18e14..257f517aa 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -155,8 +155,6 @@ contains hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return - Keff=91 - iwspr=1 nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then @@ -240,6 +238,8 @@ contains call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) +if(iwspr.ne.0.and.iwspr.ne.1.and.iwspr.ne.2) iwspr=1 ! TEMPORARY + if(iwspr.eq.0) then itype1=1 itype2=1 @@ -497,6 +497,7 @@ contains unpk77_success=.false. if(iqorw.eq.1) then maxosd=2 + Keff=91 norder=3 call timer('d240_101',0) call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & @@ -511,8 +512,9 @@ contains ntype,nharderrors,dmin) call timer('d240_74 ',1) endif + if(nharderrors .ge.0) then - if(iqor2.eq.1) then + if(iqorw.eq.1) then write(c77,'(77i1)') mod(message101(1:77)+rvec,2) call unpack77(c77,0,msg,unpk77_success) else @@ -552,8 +554,7 @@ contains endif enddo ! metrics enddo ! istart jitter -2002 continue - enddo !candidate list +2002 enddo !candidate list enddo ! iqorw return From a8b87f1f3a98badfc4dba8e5ad55a39046c91580 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 16:05:52 -0500 Subject: [PATCH 103/239] Fix wspr-mode SNR. --- lib/.fst240_decode.f90.swp | Bin 45056 -> 0 bytes lib/fst240_decode.f90 | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 lib/.fst240_decode.f90.swp diff --git a/lib/.fst240_decode.f90.swp b/lib/.fst240_decode.f90.swp deleted file mode 100644 index 80719f14301320e718670170abe1f21b1c9edddd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 zcmeI5d6X+xedpzbEtu72Si?|l2S2I1T2e{9y(Wb*&v*g+z|TuK;NhW`O5OFIy3|jl zcE9&#SWXfQWLN?O20RQ2F_W1Ph{Itr8Ngvl0^}SB%Rty6oWa9R!WzIPVLrd#y|+}_ z`q`fOCxg`I+p4a~|&;jNW}0-pyI3YR?Z_Gdok9-le)OUDX@wB2hY z$0Lc^_j5&~`S@=4_~KK0-EybfY;>lievTzrdHinNX{D9D^jQC7CG9mUop__tPW!c` z>d{uz?6#tE`(Sknm09qt2WCBRr+Z+x-(Fn1?=|&Wpbysh=goQNo^#EeCNs-0>w#Gh z%z9wf1G65O^}wtLW<4w&My_7OZ9)jHX*U!XN`Q{!`|Ouzq=#x_pgU$@^qTYxL)-Zot25L~}uB>wI;{yz5mVw#Gh%z9wf1G65O^}wtLW<4t*#nJM zp)g0ye<+MF`hUm&fAju@!Z*Ojz^lNEzz(<;Tmv2l{_%c=!bic|!0W*=a49$d?gqYc z-$LR2;MJfHt_D6h3w#$w{yX5S;49z_;5y)g1#oY0+u4P}C&1gmi@?*sW5A=p+2C6U z4L%6o1fCBLfjRIsgbg1C{|&qWycq0(O>hY)gC8QW_&e~|;Mc*W;9=mQ;A;pA{sw#q z{4sb7Xn_j24ME8Jz-dqcw;`Cg75ou+6L<-DF}Mai9$W+};B0U!LW*~TSA$o9=Yiwk zT5u8Y!9&1xGeYHJ7gD*K_G=qv?Xl>4MR8RhKUCYdLx= zUK(|xW@?DpDY9G&bJM{FGG}sQZv*R-0&9~3gGqr^3ADv; z_j;@Kur|NlZ58!;p?7`MEG{2hUtKNvwbG)SQQL!LtM#dgdcEF&SZ`{w<_VXodBP+L z)@ug`<;Cq{JMN|ZlGopg60Pg@DU6;vK|M4VQvKFR8?+Utazzl`o5cON(TPt-Uc1}# zcGHL;Z>P~beyqQ`s-*g)f3#%SAk+&V>$z)4DaA7|fGqUzg{ zt6H5#zhN>~%KhGMRIW&9?!&XlBWU3M^BijkOM;0R%_Ir)ndHvgyKk3bK*|vJE+|lV zOKRoGpjKQq6Ftc8G8#gIR3@GL&ymteqNGeVSN%K@LnzRunDRZQ&sZj#EY}>$&Sj#g z-aeUJMTawa+szYXy7PZpn~F|>IO#{5QE$HH#e2+#V!c|O4{FtFm4%Wn?Q}O|ri`5= zN!Lz-eAGsxm7YqP{%*2!e0B9`y4!3{H=E&M2qiJ!7M4`;Qj2zkj#*7Ln?+Z)Oe zrTXwd(M$V{KDX7y2!LgW?VF~tBvfcnO(K?%8~Rv z)+B5@`;CoGUMOdVrnkIR-@No=g{Mk@FuN;&G7_oozz-n(d-|ZEXh){EUdojZKs<)NTZ}b z7H2G1wa2wnc6!}r)Y|Pu#Uazyqi#hnNjJJ1rPkqr7*55@RAXgg{}oyI9Yo1^mT*^68D#pC)@>p}XY-SCt4hM%On8<36s zq!mRwe$wylM7_A%@{{P~j$L*L?RNa+^j3Om+b6HA?PTlG@;HgiIuI45{l4osUzb5Y z+3h#|p=Bm%pGdowNTJzH`i(eAr4dom(mw6A8_kG&J`$8GXYzQNq}f838yFpxtU)fF zJfowDPV8bGO@Z>U3+8ANI(FsRyQhZA% zvgDptpET+1M?l^sE`Ayb2FE37-pNT$#k`o+C2q!jFJY;4gb3{R`rgo3Wfdip?Hie# zzI6Lw#@U&9#sT-tOw*~QZ_I?Q@LPRf`qWKNud$K#WzosaDXJ(lO15JY>zAzz@-&-z zN~^L-$~8~-nU)XV+v!S&_eRzcEf&HfJyS5x^l)%N`2S1chtGy@7XE+U@{K=&zyCgX zGk6)e0jz@C;p@K#ZUzy!7TgD%4GQ2p@b;evw}5wo9dH>~2WJD}`QHM1;8(z>;NxEk zHb4bD65J2`i2A$@Y=Z{)HE=C>5_mND6`*zAkI$XO&3a(g1G65O^}wtLW<4*aI_6idzZ6{=VpODYcJ~W_7YE7MaZ?fo`mw@CTQvMCf zEhch}FgM(}9x2DrXYNRMcXP{&Qut3~86pX~>hO_5mS&6!66IFAHXrXGsmM~z9deEI zWZ%9UB~6v8m;_pUsQ(w7IGGr&d?BM@Lh>yzQE9DsycBLXP8O?WUvCzx<%9Fml=+jb zjbdDKT(C)x?D%+jGb+aouS~7V-tlsWyA2~tcAaI?9uKu03$=NX7|q8fbm;$_aKeLD zan;@Ss79_(h9C|X>;6K0DCfw{+>vOzi)fk3OD{KM3Pm07(4kAbhT{*ZJEXNvrSfLK z+}}c)w`FUdr#E+bsv-)=>~zyK7J*SVR2LRZQt6^FqnFPY8%JM`oyTyz*g+h(^H_qVpaewQao2gZ#EZHXGqE#xwhK4c6^ydkv;)(`f;(-}W=hY<=IHOU?ve$tJ})rqc;RCFSOA8)7Gmtm3#lr$Ff0jaOY$;P6& zEctRRQGp3r@#|GzO4nh|Kixv26sE=4W%U+3cUSTjxK#4F%lW#SD{)8>Qq-B6q$1B< zmN1!!jA2?Vc|8B#5<{FsD$JvUs^tQNAQx`O2@Tuu%}CaD1<*n%PnR1hH(0O{Q%aw^ zxSJg4d%fL+BHKE_Xt)+8<(N(o{{N$Ap<73{Ed0N-pZ^5BzVQAxf)qRz+!uTt9{=6o zMc^=a5cnB<{ingZ!0SK^t^^CyaK!soB%su3Dm(4(Bpp}h>rii zgXe+EKmZ;B?g2iDZvO+|Ch%Nv1T296EqZ+LGSC4bxDWUq`g+mte-?ZY+ydSLc0mYA z;K%gw2f*)vQ(zNlzyBQUOMc#(m_3vEwZ;S<50B@!8U*fa#kG)EZc#24TJqoT?{#-# zedaS#gaVoskvm@XADE)sorU5$b! zr3qB=F7c9%^s1Marg^3!QdO&pP<5-Hkq=O!qDIN?YkDu~o#s`mEdf>|>75Sz(>4Ee z-9NqLpVqyMi)r@vj@!wQ%P^z_^-Y%{jn8J&ddZE9Q(8_?o{r`VNNdM;IG5LKRcS-A zvl!@nyaS3qc4wl2mFc+e-@=I@FA!Bu+Ahz@+xDufZUI4db!6&jwtE#C)=Nt1U0M2>B**oUfZ0NaE(H zX2-E18Ih=yj)f7q*=74K^(|y6hcB$L)nw(=P*UCU4p{~jjZz9GMpk09QYS?%#R!RZ zI#W$)BFsTxu;YI3l@ru6++N{xq}eBmSRokdidD$d%dV#kyouM$L3N&W zC8!n~z0J~MjknBV5R_MKV3O{n75KKnyC)-UE_fA?QP?|4BRlw{Fp|XFk}6yhLi6-O zys3Paymj4Ma3mAWZgnS9BBf9W<=+A}C&oG@X33QI#pFEtLJlxZnH;V3rqo1dwn(C^ zvQpWhqrysKIf8Y~z&M8)46B5;Ki!!)%EIYNTsb`Z0H1z${r{KX z(S7)M;s0UH_46fo{l5mk2abUAf$09f0sbd=6L=-~w?Oj#5E>r_e+0Hb89W@^3c)`F zUGQ{J2M+^3g3tde@MdrWcotX#=YaRY>;ED6Eg(Ao$AJ5QFT>}*4*WVe3N8jdxHtF? zeEqw@%fSlxdwBSFgPXw1z#iBDPX#OBVc_22@8Rjc4ZaLM1U?8}23`uD0uF;Bcp&&3 zeEv;9?E8D50RnIy_-FWg;r)f@zX3cBTnN4ak1ss`Yb?Ki1>YBfWpDv_2)GycDE9lW z0lx{Z0_TC-k;{An`~`R$upc+1R)Uk=axr5qv)-7omNV8;`OpEcH)Acucz4EHvWuFr zmUf{un+Vj1nbXOPwRG>08EZ*T%veih^Jc82WlLwQrCT2K`~OeYa?ms*p0M2IP|H#L zqlnMP7x5|bpA@y*K61%!iUb(_Pt?OzQ5>QMj#YR?S+Bi3L6bOKD&zyX7J}i*Sny=- zcU&Z3s**XX8sd}W1Y-p82Aj%G(}HOn^+@$cdP&^O?oc<8a6%_duH+qT^(0}0=>N}! zvAh(1Q~3WIER*?Z`29ZtH-p!M7lV_a3lbnQfjW3FkaGaUCg4xNe*$6~@Ir7Mcm_BG zL`EQI0=yNOz<&V$9$X8a2p$U_3BHM3K+XYp4tN@=+c{sNi8TfmLrwcsR>GX<^&E8tvk4)`%Lh7SNaPv9kB4?GL}8jy1ZL z|A36)3*f`xZQzaI1z;Dn!IQwRf_d-=a1MAN_)F%+3qc#m9JvHc_%P|MLtuitU$79Y zn{Vv;tS;6@+lW$VyjR_AVNUH~8lAMOnkZ2};SO_s)Wh*>vyy3}#8OHPpfc4^nXFf1 zJB6d6N73kj&|Tpx){db``6Q$J-o zA-gQq3+A~tniCckV>?A)vVk3$RWr-FA|gHUaI-?;oY4M^q{u3oGn>;Ab|vpu4t8I6 zq#P%|pIDAP>tN1HcDFZB2x6wBEko~j8Yf$nS*Va~FXZczZ!cD6S`SHiEagc$E5BWUj>Yi!V zy{7R$t*!?vRWSoV&1w|?xg?@Qmg!#8NHc|U(as0fBnm1FmNs>eWcb-w&;-(j$yN~R zb5ud;>3JF?kCz74<`a1=Twu+n)Idp{|IBSSj-&0x7nSj8U{WVk zquWWnqA>(%^=nG9o$BlqD-8;0r#Ui1mvdLCR$BG@Jxnqk9jQswG@3wYX%F)qw$n=1 zPwg~RSNZZZ<3>lETB}Nz0oNuDNHDA62MVT2+Kt!%_KU@YC1DY5Z^_AQLI9Rn@v7t1qp|*SG4gVQ{gsh&S>%O6v0Cwd`tC)95uh&#FTi4o-m7_XmqpMX$<)E6I zNpa$SzL4+_M_xVnLdwOO;9$wRNffBJtOp!7!<)r8$L9_^a)%yG`j)Ku*@OH}ID=|v zFC?CiJpsWTOB3j_Ctk*CJX6p#x|q0QLa<8KV`Vs1q!eP+Zc>;qs@dGjj@*&rsDdcb zgVm*@2Lq=PMP1w6b1!(Ou3c5L#q4fGTZ-itc5SNX&2+5x5DsVLM~B9BQD_9la;}K> zS#J4~vlvPyw48MNd|)a3?xUQD46ONcYav8%}#I$&AB~xNQiM1?C8p2 zDRQ2JDa&l4cel4sxpWxW*r+`<3*U&uJ%PQi8l6LrF6NYh;&AOs)_1@?EBSJV=UT3! zZMN}IS$EPSbZtj4T(~57>=v`ZDUg!S^y!DI$JmT?kG3JJ^FdEy!ev9uD{TcO+;!IA zsh8#k62(epV+mL%%@2$@)Wl|zL)7fiZSK{RoyEgWW6}|CORE2e9WC5b z_&WH1cRv0P;OoT(K+gYrJ8-gqS9ASbZ~{CNEP->uJ;Ar(@5MjhFTp#&+rbUsde8>f zfQy010}g@;cr2NF7OZF<3MBr z{}DVFG{Mt>_!T@3tbm7uhk?()_kSAvE_gk7E_fC=3gmo&gWw$Si{LhR{#(IEfXE15 z0h-|H;7QzeHSmw{@E-^N1snyB0c9`;9tMQ3{|#_8xCoTNqrn{b7-RbakbrBzxj@GI z9>9Lgv|?)J?ZWVVQO_8BUwCCX|wT;P&+BOaRY2ZWE@27#y>8TV}Wsk?PyT`s?Pqs;|IVvpvP`nh8B6HyD z44=%pxzpWS#Fechhs?mL7;{)B5GX)Jkbi2$Lq{zR+gt7xAbvR}sN;g#TVCjiBad*s zWz1rmyr`nyf;Q{u#$KgXF41_m32JvFIi7@Y!-Ld|qp4Zu_o4&5d()`V6Gt#aB&Mez zDHY{oOA3qa#sbVX1x?|1<}Pn%dA-MGT?r+>0G%8!E=`U%B#@6ZHf|K;3Ij#k|6~$F zMOWX!LhC{}n+Sdq&XNoyCiloE=Qp_7g-sGOYYYK#{!*vGTtVs|<+^pFw3zEQBSpwc z376)JmgTDmhgedEwm`}F$?1UQM~J>+KypV_Ne$;Ni#NA&PL`c`+nD*`PiH6$2CXrP zfH(JK=56MC>P9Z3!-IjDVa4n(TjIeg&x91c&u30t$kN?y>uR~(NKPRFOHvivAPT$W zlB)}3hgc|FyUYQ(R}NlSV)}yH>7ThLMW;kc<~U($q^z{?83nTCL=*Z_QqKTo15Qh{ zT3(pjAv=GZVk^~hZP~}ifMf8=tGvLN?RsH@YRdz2e(|AQtgo|CnEsi&LVZ=27R5d^ z^Yl!m7U~j!gP*$5?Mox)m$!%OW!^E*5IHjqGt4X`-OjXyL`h|mOLsQggr?0Mf(y|D z+|=@2+5$H(=l*dP5<8&@S+bzHOE_ARCjzNtKA%b+vP2Uuq#so_${MIUA0#V=DbW=z zb9$H{&KjaNcgZfx6I;nm`jKfUGqTs%(A%LNp}dY$(&aAzT9UJY6k>v2F9-Q(k>+p9H-P3S^hyi52S z>g%~?t*LF&(>X;Xiuon-=55XvD+rk&Yz7t0Ew}miDNAKsU5u@TXET676p0~k*zD~o z@$T)R$roaA57(xO)R0WW$rns=XBBK-07^G63^WyE>zXggjH!4^Npym=FWy>=tH#VZ zW`6R>F~@MBI8&t{G|-XTzxD~oT^P+Z7ePbsgULiM&t6E8Hztm)pobVeWw^NFU0A( z{$CLP9V_ylM`&#+ej{Hx+{B0 z%a;GS?4_Zy@g|&F_Gx;`k*X^x`9GD^e$6;d$2w9qB_;o-lG?9UqkYY=ILd)imj6>J z?^j9bYsoB23d>ZEML*4RU7&OM#A%3Ydw@LJj%I;Cw_qSJm)k@H=SW>ip${xm)hg|n znC_~cU5TT*l247JrI3i1Ls>kQ(IFVW(0EA$f~72=E&;16*?mp!>*`yn6yUd~Y*V4n zhy6P4T`2}hy~Zg$$Z=>>Zan|OwrjX?-mHbw`-c=gdWSlAOUbR`mbE2A(7T;Q!t4_kA9I{tZCv|F^*fKzRIn zfFHx7e;s@cd=7jV2+#jNz#D<^{Bky63p@&Z7ry0Zv2M+>g zfgi%he+J0e0nY&IpbF$S1H_l$pWx}g1l|tb2%ZnF13vgR{JfkWAUgf$fdmN8e-(Hl zxE#pu1uTNQgCD@-zaP8yQ{^P+z!EKE5yTD1X2c8b(w-9ywRT#hw zGap%BjJn$@q+^beNFx+<1(!r-X)X<-G?&IbhBEgJk+AA#%5z<2AY!&%>OFc?Ucu&l zKIQG~+y&iBI`g)n5@W)B{2^KR(hUv|g1J}6bI}hfGh9Nw=-BRjI-^3&#~K1=Gc?$( z7L7~g5>D7gIKWrt%ovWPtGkC%_6g(BrWw*tl2bhEzg%MoOR5sk3OWPxN6!eO_)bD&gOR0gL*+?c*LZs1yf<|d35D=e%MxM zBPS3R{%SzFJz?G%!eiq($Ie!d9Ks2aLwDuetwHAxM%lBq8pLH!MQEBkEdgVfJuEg& ztM5F4L(e_5qQmD^h~dLrf)EIyk%yfDa=-uq3focGJ4}V-0Bku1zSn1C(6{^m?#1r$ z&Prl`-fjvnLl@gpMH+2o?+*vLr};^nQK~z+(=ige5ABgNXqk~B}{lgNk1||83pYnt&|&rEQ$*|T>DmP zZF;5FT&0GU^;rqp{Zjkv*n=A9NyrpL#A}2RYgT~31`MbCntIW%x##%K5OR`;JfRT> zPkDf~bUha;pejfa(ycu?9V8>SkPn@1mwO4Kl3|dEXHB4nlXPi9_>ip}ZMDnJ z@QfIQ4^Lkvpa{h5#)i(wKhLIY8<@-ItV7hJ%w`>XuSk=FDJ>3iYm000gr;dfW*xvq zA%DZQj4IpyWp@0ssTq&9f*E&IzfD&fCZx?7p=@q>^BL{JPG=X1GU7xG23UDH7bf+L z8Uve2Wx`z&N6^{_#$>Z)15KTa}0ILgm~;PCMjS5>fBhJQet6t&zbS zny=8!hAp?9A%i|ZJkIP--B?dvVX?Bd?Ywi_)=a9zPOo5$RmG%I{^8WpCBSj+Nj3Me%4r)o+y1~2l#jz>~o zO!cfKuA0*hs_QkplpR9W5T`O5njw&Oz1E84=Sqh6H?mF1_VK)+$72V|L8)PW`y+2) z23f{LUo+;?t^Ue@xc8G;rR-4)AyycY$(^ErtVC}0qkHcOf@%BK{l5@Oi&%QjyENh# z3-s7Tep;*7Jt+s9TKmXs0J8p%BO~T;0%9v?7_}B%ua$foR&!?8gz5Xn%v2-SHfgNH zGw>HVJjwX~pMqa)!0QVCUsoOwz8*gR-QXthY_JLb6}Sz4{wF|q|965D-~jjny!r;630KpaoXIy@1&9zYB=%zMT8N1Re^$0grwQcqtHl{KeqG;A`;e?*K0b zJD>}m2p$3C+`o^2KL@vf-vz$~PJj&{?Rp38`+e{tAm;$c82}dp5BwNj{G&kh@m=s> z@aOR0F9+8HvAHjS2Z8&7Pr`4%6Wj=n1F^Bc8ay2Q4F39y;AY_X@55Zzf!Nc389rNn zw@+;8F8~h&KRb*50G|T4fY$>3xEU$m!zN85_97->?i7hp)<_QW8D0!C+J)?ji}Ba@ zv_QgTJvBc#CNIL3k|#ebWPX_~6n~%1dHpf2Vz6$19x7kbSbnVW#`DWhOWmQ|7!8i+ z*59g{l3h}Be#lzMR@GV^X;5LLqTJdabTX%yxOYT8nMshzT(hX*PFgZnNx5!Y9t!bn zPs*0U8!Snd+QiWz?yj~)T7TEuVh#Oa&PINQk>4LIc!jJ7%*Fn7=cmO+$AO?x8c@o{ zL2}&nx?5>LuI}=qiCS^3?r6z(wD$5dY5G%vqXhonRXy7b(eH<@94#j|-B1bC-O+)W zMW-+}P|!onAaIypM`CZsZ|cB5BrQ(<;@CI+*~0w^*MKrQWYiW2yIT(|GFr+BA~7G1R6; zf%=&bJ>S^BO?d&7Nxfg2#!~Owrt#GKwJD$4JxXD%yap5Fnj;(4!2y>lQe9%dXx@QY zqU>Vs{PWNEu9Y7fU_;<>Gaxjef?_pTNU*#}u*^uX+(?YMhoQnv*yOzbe$oCwXq9J{ zXH6EOqW$$(u`H6Gh&BJ^_h8l5NbI+B?*>Q@QL5E=o~gZ|WOHa?(<(C;^e-hWui@}&H`7SC&6W;ipTOwdqgo=EigopJx{g zv5-@{5m;hbgDFMkZaSz96(vf=Vq-NO2s#(63U)Z(K#|M#*C}c7S`q#KKfwoo0X|vy ze_m1g`6|5rUxAl`r-AdpKf~vL1^f*V-v4)i`1y;T|5t(h7J%68zYRPcoCW?Ce*Ycd zwO|{FU;mZh;oxWR{9gn&gB!tXz%#)ia31(Ry#E)$7r-mP9+2|@4*-z~ya^lw*MLKy z3PdJQ0NNhgmf6>=2WCAm>w#Gh%z9wf13yPSU^e9D|4fFS?+vbHH#v~t&t&L#K_4)a zp(E|R;?yBI3t%QgpUKdjtbHa!FXR_nS!qRYK(|bnp^L Date: Tue, 30 Jun 2020 16:06:53 -0500 Subject: [PATCH 104/239] Remove temporary stuff. --- lib/fst240_decode.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 7099ebc5a..6dfa3643d 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -238,8 +238,6 @@ contains call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) -if(iwspr.ne.0.and.iwspr.ne.1.and.iwspr.ne.2) iwspr=1 ! TEMPORARY -iwspr=1 if(iwspr.eq.0) then itype1=1 itype2=1 From ae54c80a545c7da8dab2e634820fd635f79aba11 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 30 Jun 2020 17:14:58 -0400 Subject: [PATCH 105/239] Here's a start on GUI changes to support FST240W as well as FST240. --- lib/decoder.f90 | 3 +++ lib/fst240_decode.f90 | 1 - widgets/mainwindow.cpp | 11 +++++++++++ widgets/mainwindow.h | 1 + widgets/mainwindow.ui | 12 ++++++++++++ widgets/widegraph.cpp | 4 ++-- widgets/widegraph.ui | 4 ++-- 7 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 261591f3f..c6282c484 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -189,6 +189,9 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.240) then ! We're in FST240/FST240W mode + ndepth=iand(params%ndepth,3) + iwspr=0 + if(iand(params%ndepth,128).ne.0) iwspr=2 call timer('dec240 ',0) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f899f544c..f177dc76d 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -155,7 +155,6 @@ contains hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return Keff=91 - iwspr=1 nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 1ff8edaac..eabece958 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -953,6 +953,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->actionInclude_averaging->setChecked(m_ndepth&16); ui->actionInclude_correlation->setChecked(m_ndepth&32); ui->actionEnable_AP_DXcall->setChecked(m_ndepth&64); + ui->actionAlso_FST240W->setChecked(m_ndepth&128); m_UTCdisk=-1; m_fCPUmskrtd=0.0; @@ -2927,6 +2928,7 @@ void MainWindow::decode() //decode() if (!ui->actionInclude_averaging->isVisible ()) depth &= ~16; if (!ui->actionInclude_correlation->isVisible ()) depth &= ~32; if (!ui->actionEnable_AP_DXcall->isVisible ()) depth &= ~64; + if (!ui->actionAlso_FST240W->isVisible ()) depth &= ~128; dec_data.params.ndepth=depth; dec_data.params.n2pass=1; if(m_config.twoPass()) dec_data.params.n2pass=2; @@ -5833,6 +5835,7 @@ void MainWindow::on_actionFST240_triggered() m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); switch_mode (Modes::FST240); + m_wideGraph->setMode(m_mode); statusChanged(); } @@ -6443,6 +6446,7 @@ void MainWindow::switch_mode (Mode mode) ui->label_6->setVisible(false); ui->label_7->setVisible(false); } + ui->actionAlso_FST240W->setVisible(m_mode.startsWith("FST240")); } void MainWindow::WSPR_config(bool b) @@ -6527,6 +6531,8 @@ void MainWindow::on_actionInclude_averaging_toggled (bool checked) m_ndepth ^= (-checked ^ m_ndepth) & 0x00000010; } + + void MainWindow::on_actionInclude_correlation_toggled (bool checked) { m_ndepth ^= (-checked ^ m_ndepth) & 0x00000020; @@ -6537,6 +6543,11 @@ void MainWindow::on_actionEnable_AP_DXcall_toggled (bool checked) m_ndepth ^= (-checked ^ m_ndepth) & 0x00000040; } +void MainWindow::on_actionAlso_FST240W_toggled (bool checked) +{ + m_ndepth ^= (-checked ^ m_ndepth) & 0x00000080; +} + void MainWindow::on_actionErase_ALL_TXT_triggered() //Erase ALL.TXT { int ret = MessageBox::query_message (this, tr ("Confirm Erase"), diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 001742f7f..b3b297c85 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -265,6 +265,7 @@ private slots: void on_fox_log_action_triggered (); void on_actionColors_triggered(); void on_actionInclude_averaging_toggled (bool); + void on_actionAlso_FST240W_toggled (bool); void on_actionInclude_correlation_toggled (bool); void on_actionEnable_AP_DXcall_toggled (bool); void VHF_features_enabled(bool b); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index b45784cf0..2f2704c65 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2829,6 +2829,7 @@ list. The list can be maintained in Settings (F2). + @@ -3523,6 +3524,17 @@ list. The list can be maintained in Settings (F2). FST240W + + + true + + + true + + + Also FST240W + + diff --git a/widgets/widegraph.cpp b/widgets/widegraph.cpp index a78874c79..9e7f6667d 100644 --- a/widgets/widegraph.cpp +++ b/widgets/widegraph.cpp @@ -294,7 +294,7 @@ void WideGraph::setTxFreq(int n) //setTxFreq void WideGraph::setMode(QString mode) //setMode { m_mode=mode; - ui->fSplitSpinBox->setEnabled(m_mode=="JT9+JT65"); + ui->fSplitSpinBox->setEnabled(m_mode=="JT9+JT65" or m_mode.startsWith("FST240")); ui->widePlot->setMode(mode); ui->widePlot->DrawOverlay(); ui->widePlot->update(); @@ -368,7 +368,7 @@ void WideGraph::setRxBand (QString const& band) else { ui->fSplitSpinBox->setValue (m_fMinPerBand.value (band, 2500).toUInt ()); - ui->fSplitSpinBox->setEnabled (m_mode=="JT9+JT65"); + ui->fSplitSpinBox->setEnabled (m_mode=="JT9+JT65" or m_mode.startsWith("FST240")); } ui->widePlot->setRxBand(band); setRxRange (); diff --git a/widgets/widegraph.ui b/widgets/widegraph.ui index fce5f1072..7deea52c8 100644 --- a/widgets/widegraph.ui +++ b/widgets/widegraph.ui @@ -362,10 +362,10 @@ <html><head/><body><p>Decode JT9 only above this frequency</p></body></html> - JT9 + Hz - JT65 + Split 0 From f6a8a179dc627fd283c9404a33c651c53578200c Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 18:15:35 -0500 Subject: [PATCH 106/239] Hardwire for 50-bit messages. --- lib/fst240_decode.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index ab2013e5c..720d5ec8b 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -238,7 +238,7 @@ contains r_data(nfft1+1:nfft1+2)=0.0 call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) - +iwspr=1 if(iwspr.eq.0) then itype1=1 itype2=1 @@ -437,7 +437,7 @@ contains apmag=maxval(abs(llra))*1.1 ntmax=nblock+nappasses(nQSOProgress) if(lapcqonly) ntmax=nblock+1 - if(ndepth.eq.1) ntmax=nblock + if(ndeep.eq.1) ntmax=nblock apmask=0 if(iqorw.eq.2) then ! 50-bit msgs, no ap decoding From 22b782a4aee8ea40c1d688bea0de8cc01886b5aa Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 30 Jun 2020 20:04:44 -0400 Subject: [PATCH 107/239] Can now decode FST240W signals from WSJT-X, using FST240 and the option "Decode -> Also FST240W". --- lib/decoder.f90 | 3 ++- lib/fst240_decode.f90 | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index c6282c484..710c4844e 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -192,10 +192,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ndepth=iand(params%ndepth,3) iwspr=0 if(iand(params%ndepth,128).ne.0) iwspr=2 +! if(iand(params%ndepth,128).ne.0) iwspr=1 call timer('dec240 ',0) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & - params%nsubmode,params%ndepth,params%ntr,params%nexp_decode, & + params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%ntol,params%nzhsym,params%emedelay, & logical(params%lapcqonly),params%napwid,mycall,hiscall, & params%nfsplit,iwspr) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 720d5ec8b..f340e8d29 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -238,7 +238,9 @@ contains r_data(nfft1+1:nfft1+2)=0.0 call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) -iwspr=1 +! write(*,3001) iwspr,nfa,nfb,nfsplit,ndeep +!3001 format('a',5i5) +! iwspr=1 !### For hardwired tests ### if(iwspr.eq.0) then itype1=1 itype2=1 From 0f04f3285aec7183170f82a9c06c2412e923f5a7 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 1 Jul 2020 08:20:38 -0500 Subject: [PATCH 108/239] Prevent decodes that fail to unpack from being printed. --- lib/fst240_decode.f90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f340e8d29..09b16c2ef 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -547,12 +547,14 @@ contains else xsnr=-99.9 endif + else + cycle endif nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud !write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & -! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,x!dt,fsig,msg +! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr) goto 2002 From f2c3cbf9ac1178ac07aad9897a9c74dae904e7a6 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 12:01:47 -0400 Subject: [PATCH 109/239] Implement basic functiionality of FST240W in the GUI. --- lib/decoder.f90 | 24 ++++++++++++---- lib/jt9.f90 | 11 ++++++-- widgets/mainwindow.cpp | 62 +++++++++++++++++++++++++++--------------- widgets/mainwindow.h | 2 ++ widgets/plotter.cpp | 16 ++++------- 5 files changed, 75 insertions(+), 40 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 710c4844e..fa50decdb 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -188,11 +188,10 @@ subroutine multimode_decoder(ss,id2,params,nfsample) endif if(params%nmode.eq.240) then -! We're in FST240/FST240W mode +! We're in FST240 mode ndepth=iand(params%ndepth,3) iwspr=0 - if(iand(params%ndepth,128).ne.0) iwspr=2 -! if(iand(params%ndepth,128).ne.0) iwspr=1 + if(iand(params%ndepth,128).ne.0) iwspr=1 call timer('dec240 ',0) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & @@ -204,8 +203,23 @@ subroutine multimode_decoder(ss,id2,params,nfsample) go to 800 endif - rms=sqrt(dot_product(float(id2(300000:310000)), & - float(id2(300000:310000)))/10000.0) + if(params%nmode.eq.241) then +! We're in FST240W mode + ndepth=iand(params%ndepth,3) + iwspr=1 + call timer('dec240 ',0) + call my_fst240%decode(fst240_decoded,id2,params%nutc, & + params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & + params%nsubmode,ndepth,params%ntr,params%nexp_decode, & + params%ntol,params%nzhsym,params%emedelay, & + logical(params%lapcqonly),params%napwid,mycall,hiscall, & + params%nfsplit,iwspr) + call timer('dec240 ',1) + go to 800 + endif + + rms=sqrt(dot_product(float(id2(60001:61000)), & + float(id2(60001:61000)))/1000.0) if(rms.lt.2.0) go to 800 ! Zap data at start that might come from T/R switching transient? diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 679c2ef22..dcfbb07b6 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -26,7 +26,7 @@ program jt9 fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0,nQSOProg=0 logical :: read_files = .true., tx9 = .false., display_help = .false., & bLowSidelobes = .false. - type (option) :: long_options(28) = [ & + type (option) :: long_options(29) = [ & option ('help', .false., 'h', 'Display this help message', ''), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', & @@ -55,6 +55,7 @@ program jt9 option ('ft4', .false., '5', 'FT4 mode', ''), & option ('jt65', .false.,'6', 'JT65 mode', ''), & option ('fst240', .false., '7', 'FST240 mode', ''), & + option ('fst240w', .false., 'W', 'FST240W mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & @@ -80,11 +81,12 @@ program jt9 common/decstats/ntry65a,ntry65b,n65a,n65b,num9,numfano data npatience/1/,nthreads/1/ + iwspr=0 nsubmode = 0 TRperiod=60.d0 do - call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654qTL:S:H:c:G:x:g:X:Q:', & + call getopt('hs:e:a:b:r:m:p:d:f:w:t:987654WqTL:S:H:c:G:x:g:X:Q:', & long_options,c,optarg,arglen,stat,offset,remain,.true.) if (stat .ne. 0) then exit @@ -129,6 +131,7 @@ program jt9 if (mode.lt.65) mode = mode + 65 case ('7') mode = 240 + iwspr=0 case ('8') mode = 8 case ('9') @@ -137,6 +140,9 @@ program jt9 tx9 = .true. case ('w') read (optarg(:arglen), *) npatience + case ('W') + mode = 241 + iwspr=1 case ('c') read (optarg(:arglen), *) mycall case ('G') @@ -256,6 +262,7 @@ program jt9 shared_data%params%kin=64800 if(mode.eq.240) shared_data%params%kin=720000 !### 60 s periods ### shared_data%params%nzhsym=nhsym + if(mode.eq.240 .and. iwspr.eq.1) ndepth=ior(ndepth,128) shared_data%params%ndepth=ndepth shared_data%params%lft8apon=.true. shared_data%params%ljt65apon=.true. diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index eabece958..6b25770b8 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -429,7 +429,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); - ui->sbTR_FST240W->values ({120, 300}); + ui->sbTR_FST240W->values ({15, 30, 60, 120, 300}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -1128,6 +1128,7 @@ void MainWindow::writeSettings() m_settings->setValue("NoOwnCall",ui->cbNoOwnCall->isChecked()); m_settings->setValue ("BandHopping", ui->band_hopping_group_box->isChecked ()); m_settings->setValue ("TRPeriod", ui->sbTR->value ()); + m_settings->setValue ("TRPeriod_FST240W", ui->sbTR_FST240W->value ()); m_settings->setValue("FastMode",m_bFastMode); m_settings->setValue("Fast9",m_bFast9); m_settings->setValue ("CQTxfreq", ui->sbCQTxFreq->value ()); @@ -1200,6 +1201,7 @@ void MainWindow::readSettings() m_bFast9=m_settings->value("Fast9",false).toBool(); m_bFastMode=m_settings->value("FastMode",false).toBool(); ui->sbTR->setValue (m_settings->value ("TRPeriod", 15).toInt()); + ui->sbTR_FST240W->setValue (m_settings->value ("TRPeriod_FST240W", 15).toInt()); m_lastMonitoredFrequency = m_settings->value ("DialFreq", QVariant::fromValue (default_frequency)).value (); ui->WSPRfreqSpinBox->setValue(0); // ensure a change is signaled @@ -2971,6 +2973,7 @@ void MainWindow::decode() //decode() m_BestCQpriority=""; } if(m_mode=="FST240") dec_data.params.nmode=240; + if(m_mode=="FST240W") dec_data.params.nmode=241; dec_data.params.ntrperiod=m_TRperiod; dec_data.params.nsubmode=m_nSubMode; if(m_mode=="QRA64") dec_data.params.nsubmode=100 + m_nSubMode; @@ -3749,25 +3752,7 @@ void MainWindow::guiUpdate() QByteArray ba0; if(m_mode.startsWith ("WSPR")) { - QString sdBm,msg0,msg1,msg2; - sdBm = sdBm.asprintf(" %d",m_dBm); - m_tx=1-m_tx; - int i2=m_config.my_callsign().indexOf("/"); - if(i2>0 - || (6 == m_config.my_grid ().size () - && !ui->WSPR_prefer_type_1_check_box->isChecked ())) { - if(i2<0) { // "Type 2" WSPR message - msg1=m_config.my_callsign() + " " + m_config.my_grid().mid(0,4) + sdBm; - } else { - msg1=m_config.my_callsign() + sdBm; - } - msg0="<" + m_config.my_callsign() + "> " + m_config.my_grid()+ sdBm; - if(m_tx==0) msg2=msg0; - if(m_tx==1) msg2=msg1; - } else { - msg2=m_config.my_callsign() + " " + m_config.my_grid().mid(0,4) + sdBm; // Normal WSPR message - } - ba=msg2.toLatin1(); + ba=WSPR_message().toLatin1(); } else { if(SpecOp::HOUND == m_config.special_op_id() and m_ntx!=3) { //Hound transmits only Tx1 or Tx3 m_ntx=1; @@ -3881,6 +3866,10 @@ void MainWindow::guiUpdate() int ichk=0; int iwspr=0; char fst240msgbits[101]; + if(m_mode=="FST240W") { + ba=WSPR_message().toLatin1(); + ba2msg(ba,message); + } genfst240_(message,&ichk,msgsent,const_cast (fst240msgbits), const_cast(itone), &iwspr, 37, 37); int hmod=int(pow(2.0,double(m_nSubMode))); @@ -5841,6 +5830,7 @@ void MainWindow::on_actionFST240_triggered() void MainWindow::on_actionFST240W_triggered() { + on_actionFST240_triggered(); m_mode="FST240W"; m_modeTx="FST240W"; WSPR_config(true); @@ -5851,8 +5841,8 @@ void MainWindow::on_actionFST240W_triggered() setup_status_bar (bVHF); m_TRperiod = ui->sbTR->value (); ui->band_hopping_group_box->setVisible(false); - ui->sbTR->setMinimum(120); - ui->sbTR->setMaximum(300); + ui->sbTR_FST240W->setMinimum(15); //### 120 ?? ### + ui->sbTR_FST240W->setMaximum(300); ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); @@ -7450,6 +7440,11 @@ void MainWindow::on_sbTR_valueChanged(int value) statusUpdate (); } +void MainWindow::on_sbTR_FST240W_valueChanged(int value) +{ + on_sbTR_valueChanged(value); +} + QChar MainWindow::current_submode () const { QChar submode {0}; @@ -9106,3 +9101,26 @@ void MainWindow::remote_configure (QString const& mode, quint32 frequency_tolera tx_watchdog (false); QApplication::alert (this); } + +QString MainWindow::WSPR_message() +{ + QString sdBm,msg0,msg1,msg2; + sdBm = sdBm.asprintf(" %d",m_dBm); + m_tx=1-m_tx; + int i2=m_config.my_callsign().indexOf("/"); + if(i2>0 + || (6 == m_config.my_grid ().size () + && !ui->WSPR_prefer_type_1_check_box->isChecked ())) { + if(i2<0) { // "Type 2" WSPR message + msg1=m_config.my_callsign() + " " + m_config.my_grid().mid(0,4) + sdBm; + } else { + msg1=m_config.my_callsign() + sdBm; + } + msg0="<" + m_config.my_callsign() + "> " + m_config.my_grid()+ sdBm; + if(m_tx==0) msg2=msg0; + if(m_tx==1) msg2=msg1; + } else { + msg2=m_config.my_callsign() + " " + m_config.my_grid().mid(0,4) + sdBm; // Normal WSPR message + } + return msg2; +} diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index b3b297c85..3e5d80747 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -299,6 +299,7 @@ private slots: void on_actionErase_reference_spectrum_triggered(); void on_actionMeasure_phase_response_triggered(); void on_sbTR_valueChanged (int); + void on_sbTR_FST240W_valueChanged (int); void on_sbFtol_valueChanged (int); void on_cbFast9_clicked(bool b); void on_sbCQTxFreq_valueChanged(int n); @@ -729,6 +730,7 @@ private: void setRig (Frequency = 0); // zero frequency means no change void WSPR_history(Frequency dialFreq, int ndecodes); QString WSPR_hhmm(int n); + QString WSPR_message(); void fast_config(bool b); void CQTxFreq(); void useNextCall(); diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 5ac16038c..26f412448 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -184,7 +184,6 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed) if (swide[i]<1.e29) painter1.setPen(g_ColorTbl[y1]); painter1.drawPoint(i,m_j); } - m_line++; float y2min=1.e30; @@ -414,7 +413,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() float bw=9.0*12000.0/m_nsps; //JT9 if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 - if(m_mode=="FST240") { + if(m_mode.startsWith("FST240")) { int h=int(pow(2.0,m_nSubMode)); int nsps=800; if(m_TRperiod==30) nsps=1680; @@ -500,7 +499,8 @@ void CPlotter::DrawOverlay() //DrawOverlay() int yTxTop=12; int yRxBottom=yTxTop + 2*yh + 4; if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" - or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") { + or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" + or m_mode.startsWith("FST240")) { if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) { painter0.setPen(penGreen); @@ -531,18 +531,17 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,yRxBottom-yh,x1,yRxBottom); painter0.drawLine(x1,yRxBottom,x2,yRxBottom); painter0.drawLine(x2,yRxBottom-yh,x2,yRxBottom); - if(m_mode=="FST240") { + if(m_mode.startsWith("FST240")) { x1=XfromFreq(m_rxFreq-m_tol); x2=XfromFreq(m_rxFreq+m_tol); painter0.drawLine(x1,26,x2,26); // Mark the Tol range } - } } if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8" - or m_mode=="FT4" or m_mode=="FST240") { + or m_mode=="FT4" or m_mode.startsWith("FST240")) { painter0.setPen(penRed); x1=XfromFreq(m_txFreq); x2=XfromFreq(m_txFreq+bw); @@ -551,11 +550,6 @@ void CPlotter::DrawOverlay() //DrawOverlay() x1=XfromFreq(m_txFreq-0.5*bw); x2=XfromFreq(m_txFreq+0.5*bw); } - if(m_mode=="WSPR-LF") { - bw=3*12000.0/8640.0; //WSPR-LF - x1=XfromFreq(m_txFreq-0.5*bw); - x2=XfromFreq(m_txFreq+0.5*bw); - } // Draw the red "goal post" painter0.drawLine(x1,yTxTop,x1,yTxTop+yh); painter0.drawLine(x1,yTxTop,x2,yTxTop); From 8903041aa97ab61e2ccc034e91de3700465d395a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 12:10:42 -0400 Subject: [PATCH 110/239] Fix the startup value of TRperiod for FST240W mode. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6b25770b8..ef5da51f2 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5839,7 +5839,7 @@ void MainWindow::on_actionFST240W_triggered() displayWidgets(nWidgets("000001000000000001010000000000000")); bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); - m_TRperiod = ui->sbTR->value (); + m_TRperiod = ui->sbTR_FST240W->value (); ui->band_hopping_group_box->setVisible(false); ui->sbTR_FST240W->setMinimum(15); //### 120 ?? ### ui->sbTR_FST240W->setMaximum(300); From eb1c60e4544fede13ec165c248b84ed4cc3e4aee Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 13:17:07 -0400 Subject: [PATCH 111/239] Remove several more vestiges of WSPR-LF mode. --- widgets/mainwindow.cpp | 3 +-- widgets/mainwindow.ui | 17 ----------------- widgets/plotter.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ef5da51f2..d6d191f08 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1564,7 +1564,6 @@ void MainWindow::dataSink(qint64 frames) void MainWindow::startP1() { - // if(WSPR-LF) ... was here p1.start (QDir::toNativeSeparators (QDir {QApplication::applicationDirPath ()}.absoluteFilePath ("wsprd")), m_cmndP1); } @@ -7959,7 +7958,7 @@ void MainWindow::WSPR_scheduling () band_hopping_label.setText (hop_data.period_name_); } else { - m_WSPR_tx_next = m_WSPR_band_hopping.next_is_tx ("WSPR-LF" == m_mode); + m_WSPR_tx_next = m_WSPR_band_hopping.next_is_tx(m_mode=="FST240W"); } } diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 2f2704c65..6bc4ad595 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -3385,23 +3385,6 @@ list. The list can be maintained in Settings (F2). Equalization tools ... - - - true - - - false - - - WSPR-LF - - - Experimental LF/MF mode - - - false - - true diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 26f412448..41bf173fe 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -481,10 +481,10 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,29,x2,29); } - if(m_mode=="WSPR-LF") { - x1=XfromFreq(1600); - x2=XfromFreq(1700); - painter0.drawLine(x1,29,x2,29); + if(m_mode=="FST240W") { + x1=XfromFreq(2600); + x2=XfromFreq(2700); + painter0.drawLine(x1,26,x2,26); } if(m_mode=="FreqCal") { //FreqCal From 94f5e2925c9faddb2b8601c3109c9c64c0d2b176 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 15:04:15 -0400 Subject: [PATCH 112/239] Correct the length of id2 sent to decoder for FST240W mode. --- lib/jt9.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index dcfbb07b6..43af4673b 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -245,7 +245,7 @@ program jt9 call timer('symspec ',1) endif nhsym0=nhsym - if(nhsym.ge.181 .and. mode.ne.240) exit + if(nhsym.ge.181 .and. mode.ne.240 .and. mode.ne.241) exit endif enddo close(unit=wav%lun) From 0608521751cf2784d61c2f24e141c105fd85f1dc Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 15:12:14 -0400 Subject: [PATCH 113/239] Remove unused references to WSPR_LF. --- widgets/mainwindow.cpp | 1 - widgets/mainwindow.h | 1 - 2 files changed, 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index d6d191f08..f5f8a1139 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -589,7 +589,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->actionJT9_JT65->setActionGroup(modeGroup); ui->actionJT4->setActionGroup(modeGroup); ui->actionWSPR->setActionGroup(modeGroup); - ui->actionWSPR_LF->setActionGroup(modeGroup); ui->actionEcho->setActionGroup(modeGroup); ui->actionISCAT->setActionGroup(modeGroup); ui->actionMSK144->setActionGroup(modeGroup); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 3e5d80747..646486fb5 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -43,7 +43,6 @@ #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 From 6ebb487cd55fd8368449e52953eed903f5acc1ad Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 1 Jul 2020 14:40:37 -0500 Subject: [PATCH 114/239] Remove residual WSPR_LF that was causing build errors. Build ldpcsim240_74. --- CMakeLists.txt | 3 +++ lib/fst240/fst240sim.f90 | 5 ++--- lib/fst240/ldpcsim240_74.f90 | 6 +++--- lib/fst240_decode.f90 | 2 +- widgets/mainwindow.cpp | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87b8509ff..99e160a4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1371,6 +1371,9 @@ target_link_libraries (fst240sim wsjt_fort wsjt_cxx) add_executable (ldpcsim240_101 lib/fst240/ldpcsim240_101.f90 wsjtx.rc) target_link_libraries (ldpcsim240_101 wsjt_fort wsjt_cxx) +add_executable (ldpcsim240_74 lib/fst240/ldpcsim240_74.f90 wsjtx.rc) +target_link_libraries (ldpcsim240_74 wsjt_fort wsjt_cxx) + endif(WSJT_BUILD_UTILS) # build the main application diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index ceefa00e8..b0790a768 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -75,9 +75,8 @@ program fst240sim n3=-1 call pack77(msg37,i3,n3,c77) call genfst240(msg37,0,msgsent37,msgbits,itone,iwspr) - write(*,*) - write(*,'(a9,a37)') 'Message: ',msgsent37 + write(*,'(a9,a37,a7,i2)') 'Message: ',msgsent37,' iwspr:',iwspr write(*,1000) f00,xdt,hmod,txt,snrdb 1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) write(*,*) @@ -86,7 +85,7 @@ program fst240sim write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77) else write(*,'(a14)') 'Message bits: ' - write(*,'(50i1,1x,24i1)') msgbits + write(*,'(77i1,1x,24i1)') msgbits endif write(*,*) write(*,'(a17)') 'Channel symbols: ' diff --git a/lib/fst240/ldpcsim240_74.f90 b/lib/fst240/ldpcsim240_74.f90 index 743dff34b..78e8e6b5f 100644 --- a/lib/fst240/ldpcsim240_74.f90 +++ b/lib/fst240/ldpcsim240_74.f90 @@ -52,9 +52,9 @@ program ldpcsim240_74 write(*,*) "K : ",Keff msgbits=0 - read(c77,'(77i1)') msgbits(1:77) + read(c77,'(50i1)') msgbits(1:50) write(*,*) 'message' - write(*,'(77i1)') msgbits(1:77) + write(*,'(50i1)') msgbits(1:50) call get_crc24(msgbits,74,ncrc24) write(c24,'(b24.24)') ncrc24 @@ -118,7 +118,7 @@ write(*,'(24i1)') msgbits(51:74) ! snr2500=db+10*log10(200.0/116.0/2500.0) esn0=db+10*log10(rate) pberr=real(nberr)/(real(ntrials*N)) - write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr + write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,e10.3)") db,esn0,ngood,nue,pberr enddo diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 09b16c2ef..2cb182b38 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -553,7 +553,7 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud -!write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & +!write(21,'(i6,7i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & ! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index d6d191f08..54a16d735 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -589,7 +589,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->actionJT9_JT65->setActionGroup(modeGroup); ui->actionJT4->setActionGroup(modeGroup); ui->actionWSPR->setActionGroup(modeGroup); - ui->actionWSPR_LF->setActionGroup(modeGroup); + ui->actionWSPR->setActionGroup(modeGroup); ui->actionEcho->setActionGroup(modeGroup); ui->actionISCAT->setActionGroup(modeGroup); ui->actionMSK144->setActionGroup(modeGroup); From e63b04bb44ee147b360d458f396380ba1c9e3272 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 1 Jul 2020 15:46:17 -0400 Subject: [PATCH 115/239] Post FSt240W decodes to PSK Reporter. --- widgets/mainwindow.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index f5f8a1139..90dba7a9d 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3196,7 +3196,6 @@ void MainWindow::readFromStdout() //readFromStdout } m_tBlankLine = line_read.left(ntime); } - DecodedText decodedtext0 {QString::fromUtf8(line_read.constData())}; DecodedText decodedtext {QString::fromUtf8(line_read.constData()).remove("TU; ")}; @@ -3355,8 +3354,15 @@ void MainWindow::readFromStdout() //readFromStdout // extract details and send to PSKreporter int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged; bool okToPost=(nsec > int(4*m_TRperiod)/5); - if (stdMsg && okToPost) pskPost(decodedtext); - + if(m_mode=="FST240W" and okToPost) { + line_read=line_read.left(22) + " CQ " + line_read.trimmed().mid(22); + int n=line_read.trimmed().size(); + line_read=line_read.trimmed().left(n-3); + DecodedText FST240W_post {QString::fromUtf8(line_read.constData())}; + pskPost(FST240W_post); + } else { + if (stdMsg && okToPost) pskPost(decodedtext); + } if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) { if(m_msgAvgWidget->isVisible()) { QFile f(m_config.temp_dir ().absoluteFilePath ("avemsg.txt")); @@ -3446,7 +3452,7 @@ void MainWindow::auto_sequence (DecodedText const& message, unsigned start_toler void MainWindow::pskPost (DecodedText const& decodedtext) { - if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return; +//### if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return; QString msgmode=m_mode; if(m_mode=="JT9+JT65") { @@ -3463,6 +3469,7 @@ void MainWindow::pskPost (DecodedText const& decodedtext) int snr = decodedtext.snr(); Frequency frequency = m_freqNominal + audioFrequency; pskSetLocal (); +// qDebug() << "bb" << deCall << grid << frequency << msgmode << snr; if(grid.contains (grid_regexp)) { // qDebug() << "To PSKreporter:" << deCall << grid << frequency << msgmode << snr; psk_Reporter->addRemoteStation(deCall,grid,QString::number(frequency),msgmode, From e74595fdd5a03544d53b8737b0046d243cd51466 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 1 Jul 2020 16:42:22 -0500 Subject: [PATCH 116/239] Discard the all-zero codeword. --- lib/fst240_decode.f90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 2cb182b38..6d44f0cb7 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -515,6 +515,10 @@ contains endif if(nharderrors .ge.0) then + if(count(cw.eq.1).eq.0) then + nharderrors=-nharderrors + cycle + endif if(iqorw.eq.1) then write(c77,'(77i1)') mod(message101(1:77)+rvec,2) call unpack77(c77,0,msg,unpk77_success) From 860224e89006a86611cbaee7d0771ace2e71048f Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 09:39:11 -0400 Subject: [PATCH 117/239] Many changes to make FST240W behave in most ways like WSPR. Needs testing! --- widgets/mainwindow.cpp | 130 +++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 82 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 90dba7a9d..42d839c14 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -134,8 +134,6 @@ extern "C" { void genwspr_(char* msg, char* msgsent, int itone[], fortran_charlen_t, fortran_charlen_t); -// void genwspr_fsk8_(char* msg, char* msgsent, int itone[], fortran_charlen_t, fortran_charlen_t); - void geniscat_(char* msg, char* msgsent, int itone[], fortran_charlen_t, fortran_charlen_t); void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl, @@ -968,7 +966,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_max_dB=70; m_CQtype="CQ"; - if(m_mode.startsWith ("WSPR") and m_pctx>0) { + if(m_mode=="WSPR" and m_pctx>0) { QPalette palette {ui->sbTxPercent->palette ()}; palette.setColor(QPalette::Base,Qt::yellow); ui->sbTxPercent->setPalette(palette); @@ -1047,15 +1045,12 @@ void MainWindow::on_the_minute () } } - if (m_config.watchdog () && !m_mode.startsWith ("WSPR")) - { - if (m_idleMinutes < m_config.watchdog ()) ++m_idleMinutes; - update_watchdog_label (); - } - else - { - tx_watchdog (false); - } + if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W") { + if (m_idleMinutes < m_config.watchdog ()) ++m_idleMinutes; + update_watchdog_label (); + } else { + tx_watchdog (false); + } } //--------------------------------------------------- MainWindow destructor @@ -1395,14 +1390,12 @@ void MainWindow::dataSink(qint64 frames) bool bLowSidelobes=m_config.lowSidelobes(); symspec_(&dec_data,&k,&m_TRperiod,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, &m_df3,&m_ihsym,&m_npts8,&m_pxmax); - if(m_mode=="WSPR") wspr_downsample_(dec_data.d2,&k); + if(m_mode=="WSPR" or m_mode=="FST240W") wspr_downsample_(dec_data.d2,&k); if(m_ihsym <=0) return; if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer if(m_monitoring || m_diskData) { m_wideGraph->dataSink2(s,m_df3,m_ihsym,m_diskData); } -// if(m_mode=="FT4") ft4_rx(k); -// if(m_mode=="MSK144" or m_mode=="FT4") return; if(m_mode=="MSK144") return; fixStop(); @@ -1501,10 +1494,11 @@ void MainWindow::dataSink(qint64 frames) if(m_mode=="FT8" and m_ihsym==m_earlyDecode2 and !m_diskData) dec_data.params.nzhsym=m_earlyDecode2; QDateTime now {QDateTime::currentDateTimeUtc ()}; m_dateTime = now.toString ("yyyy-MMM-dd hh:mm"); - if(!m_mode.startsWith ("WSPR")) decode(); //Start decoder + if(m_mode!="WSPR") decode(); //Start decoder + if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return; - if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR")) { //Always save unless "Save None"; may delete later -// if(m_mode=="FT8" or m_mode=="FT4") { + if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST240W")) { + //Always save unless "Save None"; may delete later if(m_TRperiod < 60) { int n=fmod(double(now.time().second()),m_TRperiod); if(n<(m_TRperiod/2)) n=n+m_TRperiod; @@ -1522,7 +1516,7 @@ void MainWindow::dataSink(qint64 frames) m_saveWAVWatcher.setFuture (QtConcurrent::run (std::bind (&MainWindow::save_wave_file, this, m_fnameWE, &dec_data.d2[0], samples, m_config.my_callsign(), m_config.my_grid(), m_mode, m_nSubMode, m_freqNominal, m_hisCall, m_hisGrid))); - if (m_mode=="WSPR") { + if (m_mode=="WSPR" or m_mode=="FST240W") { QString c2name_string {m_fnameWE + ".c2"}; int len1=c2name_string.length(); char c2name[80]; @@ -1534,7 +1528,7 @@ void MainWindow::dataSink(qint64 frames) if (err!=0) MessageBox::warning_message (this, tr ("Error saving c2 file"), c2name); } } - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR") { QStringList t2; QStringList depth_args; t2 << "-f" << QString {"%1"}.arg (m_dialFreqRxWSPR / 1000000.0, 0, 'f', 6); @@ -1588,7 +1582,7 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int ? QString {", Sub Mode="} + QChar {'A' + sub_mode} : QString {}}) .arg (Radio::frequency_MHz_string (frequency)) - .arg (QString {!mode.startsWith ("WSPR") ? QString {", DXCall=%1, DXGrid=%2"} + .arg (QString {mode!="WSPR" ? QString {", DXCall=%1, DXGrid=%2"} .arg (his_call) .arg (his_grid).toLocal8Bit () : ""}); BWFFile::InfoDictionary list_info { @@ -1876,7 +1870,7 @@ void MainWindow::on_autoButton_clicked (bool checked) m_nclearave=1; echocom_.nsum=0; } - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR" or m_mode=="FST240W") { QPalette palette {ui->sbTxPercent->palette ()}; if(m_auto or m_pctx==0) { palette.setColor(QPalette::Base,Qt::white); @@ -2139,7 +2133,7 @@ void MainWindow::bumpFqso(int n) //bumpFqso() if (ui->RxFreqSpinBox->isEnabled ()) { ui->RxFreqSpinBox->setValue (i); } - if(ctrl and m_mode.startsWith ("WSPR")) { + if(ctrl and m_mode=="WSPR") { ui->WSPRfreqSpinBox->setValue(i); } else { if(ctrl and bTrackTx) { @@ -2324,7 +2318,7 @@ void MainWindow::setup_status_bar (bool vhf) last_tx_label.setText (QString {}); if (m_mode.contains (QRegularExpression {R"(^(Echo|ISCAT))"})) { if (band_hopping_label.isVisible ()) statusBar ()->removeWidget (&band_hopping_label); - } else if (m_mode.startsWith ("WSPR")) { + } else if (m_mode=="WSPR") { mode_label.setStyleSheet ("QLabel{background-color: #ff66ff}"); if (!band_hopping_label.isVisible ()) { statusBar ()->addWidget (&band_hopping_label); @@ -2534,7 +2528,7 @@ void MainWindow::hideMenus(bool checked) minimumSize().setWidth(770); } ui->menuBar->setVisible(!checked); - if(m_mode!="FreqCal" and m_mode!="WSPR") { + if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="FSt240W") { ui->label_6->setVisible(!checked); ui->label_7->setVisible(!checked); ui->decodedTextLabel2->setVisible(!checked); @@ -2844,7 +2838,7 @@ void MainWindow::on_DecodeButton_clicked (bool /* checked */) //Decode request if(m_mode=="MSK144") { ui->DecodeButton->setChecked(false); } else { - if(!m_mode.startsWith ("WSPR") && !m_decoderBusy) { + if(m_mode!="WSPR" && !m_decoderBusy) { dec_data.params.newdat=0; dec_data.params.nagain=1; decode(); @@ -3482,7 +3476,7 @@ void MainWindow::killFile () if (m_fnameWE.size () && !(m_saveAll || (m_saveDecoded && m_bDecoded))) { QFile f1 {m_fnameWE + ".wav"}; if(f1.exists()) f1.remove(); - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR" or m_mode=="FST240W") { QFile f2 {m_fnameWE + ".c2"}; if(f2.exists()) f2.remove(); } @@ -3493,7 +3487,7 @@ void MainWindow::on_EraseButton_clicked () { qint64 ms=QDateTime::currentMSecsSinceEpoch(); ui->decodedTextBrowser2->erase (); - if(m_mode.startsWith ("WSPR") or m_mode=="Echo" or m_mode=="ISCAT") { + if(m_mode=="WSPR" or m_mode=="Echo" or m_mode=="ISCAT" or m_mode=="FST240W") { ui->decodedTextBrowser->erase (); } else { if((ms-m_msErase)<500) { @@ -3564,7 +3558,7 @@ void MainWindow::guiUpdate() if((icw[0]>0) and (!m_bFast9)) tx2 += icw[0]*2560.0/48000.0; //Full length including CW ID if(tx2>m_TRperiod) tx2=m_TRperiod; - if(!m_txFirst and !m_mode.startsWith ("WSPR")) { + if(!m_txFirst and m_mode!="WSPR" and m_mode!="FST240W") { tx1 += m_TRperiod; tx2 += m_TRperiod; } @@ -3585,7 +3579,7 @@ void MainWindow::guiUpdate() if(m_transmitting) m_bEchoTxed=true; } - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR" or m_mode=="FST240W") { if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx m_tuneup=false; //This is not an ATU tuneup if(m_pctx==0) m_WSPR_tx_next = false; //Don't transmit if m_pctx=0 @@ -3598,16 +3592,16 @@ void MainWindow::guiUpdate() m_ntr=-1; //This says we will have transmitted m_txNext=false; ui->pbTxNext->setChecked(false); - m_bTxTime=true; //Start a WSPR Tx sequence + m_bTxTime=true; //Start a WSPR or FST240W Tx sequence } else { -// This will be a WSPR Rx sequence. +// This will be a WSPR or FST240W Rx sequence. m_ntr=1; //This says we will have received - m_bTxTime=false; //Start a WSPR Rx sequence + m_bTxTime=false; //Start a WSPR or FST240W Rx sequence } } } else { -// For all modes other than WSPR +// For all modes other than WSPR and FSt240W m_bTxTime = (t2p >= tx1) and (t2p < tx2); if(m_mode=="Echo") m_bTxTime = m_bTxTime and m_bEchoTxOK; if(m_mode=="FT8" and ui->tx5->currentText().contains("/B ")) { @@ -3627,8 +3621,7 @@ void MainWindow::guiUpdate() // Don't transmit another mode in the 30 m WSPR sub-band Frequency onAirFreq = m_freqNominal + ui->TxFreqSpinBox->value(); - if ((onAirFreq > 10139900 and onAirFreq < 10140320) and - !m_mode.startsWith ("WSPR")) { + if ((onAirFreq > 10139900 and onAirFreq < 10140320) and m_mode!="WSPR") { m_bTxTime=false; if (m_auto) auto_tx_mode (false); if(onAirFreq!=m_onAirFreq0) { @@ -3661,7 +3654,7 @@ void MainWindow::guiUpdate() } } - if (m_config.watchdog() && !m_mode.startsWith ("WSPR") + if (m_config.watchdog() && m_mode!="WSPR" && m_mode!="FST240W" && m_idleMinutes >= m_config.watchdog ()) { tx_watchdog (true); // disable transmit } @@ -3733,19 +3726,19 @@ void MainWindow::guiUpdate() if(!m_bTxTime and !m_tune) m_btxok=false; //Time to stop transmitting } - if(m_mode.startsWith ("WSPR") and + if((m_mode=="WSPR" or m_mode=="FST240W") and ((m_ntr==1 and m_rxDone) or (m_ntr==-1 and m_nseq>tx2))) { if(m_monitoring) { m_rxDone=false; } if(m_transmitting) { WSPR_history(m_freqNominal,-1); - m_bTxTime=false; //Time to stop a WSPR transmission + m_bTxTime=false; //Time to stop a WSPR or FST240W transmission m_btxok=false; } else if (m_ntr != -1) { WSPR_scheduling (); - m_ntr=0; //This WSPR Rx sequence is complete + m_ntr=0; //This WSPR or FST240W Rx sequence is complete } } @@ -3756,7 +3749,7 @@ void MainWindow::guiUpdate() QByteArray ba; QByteArray ba0; - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR") { ba=WSPR_message().toLatin1(); } else { if(SpecOp::HOUND == m_config.special_op_id() and m_ntx!=3) { //Hound transmits only Tx1 or Tx3 @@ -4022,7 +4015,7 @@ void MainWindow::guiUpdate() } if (g_iptt == 1 && m_iptt0 == 0) { auto const& current_message = QString::fromLatin1 (msgsent); - if(m_config.watchdog () && !m_mode.startsWith ("WSPR") + if(m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W" && current_message != m_msgSent0) { tx_watchdog (false); // in case we are auto sequencing m_msgSent0 = current_message; @@ -4211,7 +4204,7 @@ void MainWindow::startTx2() ui->signal_meter_widget->setValue(0,0); if(m_mode=="Echo" and !m_tune) m_bTransmittedEcho=true; - if(m_mode.startsWith ("WSPR") and !m_tune) { + if((m_mode=="WSPR" or m_mode=="FST240W") and !m_tune) { if (m_config.TX_messages ()) { t = " Transmitting " + m_mode + " ----------------------- " + m_config.bands ()->find (m_freqNominal); @@ -4247,7 +4240,7 @@ void MainWindow::stopTx2() on_stopTxButton_clicked (); m_nTx73 = 0; } - if((m_mode.startsWith("WSPR") and m_ntr==-1) and !m_tuneup) { + if(((m_mode=="WSPR" or m_mode=="FST240W") and m_ntr==-1) and !m_tuneup) { m_wideGraph->setWSPRtransmitted(); WSPR_scheduling (); m_ntr=0; @@ -6140,8 +6133,8 @@ void MainWindow::on_actionJT9_JT65_triggered() void MainWindow::on_actionJT65_triggered() { - if(m_mode=="JT4" or m_mode.startsWith ("WSPR")) { -// If coming from JT4 or WSPR mode, pretend temporarily that we're coming + if(m_mode=="JT4" or m_mode=="WSPR" or m_mode=="FST240W") { +// If coming from JT4, WSPR, or FST240W mode, pretend temporarily that we're coming // from JT9 and click the pbTxMode button m_modeTx="JT9"; on_pbTxMode_clicked(); @@ -6269,7 +6262,9 @@ void MainWindow::on_actionMSK144_triggered() if("QRA64"==m_mode) ui->actionQRA64->setChecked(true); if("WSPR"==m_mode) ui->actionWSPR->setChecked(true); if("Echo"==m_mode) ui->actionEcho->setChecked(true); - if("FreqCal"==m_mode) ui->actionFreqCal->setChecked(true); + if("FreqCal"==m_mode) ui->actionFreqCal->setChecked(true); + if("FST240"==m_mode) ui->actionFST240->setChecked(true); + if("FST240W"==m_mode) ui->actionFST240W->setChecked(true); // Make sure that MSK144 is not checked. ui->actionMSK144->setChecked(false); MessageBox::warning_message (this, tr ("Improper mode"), @@ -6655,7 +6650,7 @@ void MainWindow::band_changed (Frequency f) } if (m_bandEdited) { - if (!m_mode.startsWith ("WSPR")) { // band hopping preserves auto Tx + if (m_mode!="WSPR") { // band hopping preserves auto Tx if (f + m_wideGraph->nStartFreq () > m_freqNominal + ui->TxFreqSpinBox->value () || f + m_wideGraph->nStartFreq () + m_wideGraph->fSpan () <= m_freqNominal + ui->TxFreqSpinBox->value ()) { @@ -6681,7 +6676,7 @@ void MainWindow::band_changed (Frequency f) void MainWindow::enable_DXCC_entity (bool on) { - if (on and !m_mode.startsWith ("WSPR") and m_mode!="Echo") { + if (on and m_mode!="WSPR" and m_mode!="FST240W" and m_mode!="Echo") { //m_logBook.init(); // re-read the log and cty.dat files // ui->gridLayout->setColumnStretch(0,55); // adjust proportions of text displays // ui->gridLayout->setColumnStretch(1,45); @@ -6965,7 +6960,7 @@ void MainWindow::setXIT(int n, Frequency base) void MainWindow::setFreq4(int rxFreq, int txFreq) { if (ui->RxFreqSpinBox->isEnabled ()) ui->RxFreqSpinBox->setValue(rxFreq); - if(m_mode.startsWith ("WSPR")) { + if(m_mode=="WSPR" or m_mode=="FST240W") { ui->WSPRfreqSpinBox->setValue(txFreq); } else { if (ui->TxFreqSpinBox->isEnabled ()) { @@ -7036,30 +7031,6 @@ void MainWindow::handle_transceiver_update (Transceiver::TransceiverState const& || !(ui->cbCQTx->isEnabled () && ui->cbCQTx->isVisible () && ui->cbCQTx->isChecked()))) { m_lastDialFreq = m_freqNominal; m_secBandChanged=QDateTime::currentMSecsSinceEpoch()/1000; - /* - if(s.frequency () < 30000000u && !m_mode.startsWith ("WSPR")) { - // Write freq changes to ALL.TXT only below 30 MHz. - QFile f2 {m_config.writeable_data_dir ().absoluteFilePath ("ALL.TXT")}; - if (f2.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { - QTextStream out(&f2); - out << QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd hh:mm") - << " " << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6) << " MHz " - << m_mode -#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0) - << Qt::endl -#else - << endl -#endif - ; - f2.close(); - } else { - MessageBox::warning_message (this, tr ("File Error") - ,tr ("Cannot open \"%1\" for append: %2") - .arg (f2.fileName ()).arg (f2.errorString ())); - } - } - */ - if (m_config.spot_to_psk_reporter ()) { pskSetLocal (); } @@ -7369,14 +7340,9 @@ void MainWindow::transmitDisplay (bool transmitting) ui->pbT2R->setEnabled (QSY_allowed); } - if (!m_mode.startsWith ("WSPR")) { + if (m_mode!="WSPR" and m_mode!="FST240W") { if(m_config.enable_VHF_features ()) { -//### During tests, at least, allow use of Tx Freq spinner with VHF features enabled. - // used fixed 1000Hz Tx DF for VHF & up QSO modes -// ui->TxFreqSpinBox->setValue(1000); -// ui->TxFreqSpinBox->setEnabled (false); ui->TxFreqSpinBox->setEnabled (true); -//### } else { ui->TxFreqSpinBox->setEnabled (QSY_allowed and !m_bFastMode); ui->pbR2T->setEnabled (QSY_allowed); @@ -7644,7 +7610,7 @@ void MainWindow::replayDecodes () if (message.size() >= 4 && message.left (4) != "----") { auto const& parts = message.split (' ', SkipEmptyParts); - if (parts.size () >= 5 && parts[3].contains ('.')) // WSPR + if (parts.size () >= 5 && parts[3].contains ('.')) // { postWSPRDecode (false, parts); } @@ -8219,7 +8185,7 @@ void MainWindow::tx_watchdog (bool triggered) void MainWindow::update_watchdog_label () { - if (m_config.watchdog () && !m_mode.startsWith ("WSPR")) + if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W") { watchdog_label.setText (tr ("WD:%1m").arg (m_config.watchdog () - m_idleMinutes)); watchdog_label.setVisible (true); From 6d0d21670eea798ea7dbfc6979e8b247807526ac Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 2 Jul 2020 08:45:37 -0500 Subject: [PATCH 118/239] Change noise_bw to xnoise_bw so that it is real. --- lib/fst240_decode.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 6d44f0cb7..d715188c5 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -711,14 +711,14 @@ contains ib=nint(min(4800.0,fb)/df2) !High frequency limit signal_bw=4*(12000.0/nsps)*hmod analysis_bw=min(4800.0,fb)-max(100.0,fa) - noise_bw=10.0*signal_bw !Is this a good compromise? - if(analysis_bw.gt.noise_bw) then + xnoise_bw=10.0*signal_bw !Is this a good compromise? + if(analysis_bw.gt.xnoise_bw) then ina=ia inb=ib else fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, - fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw - fh = min(4800.0,fcenter+noise_bw/2.)/df2 + fl = max(100.0,fcenter-xnoise_bw/2.)/df2 !we'll search over noise_bw + fh = min(4800.0,fcenter+xnoise_bw/2.)/df2 ina=nint(fl) inb=nint(fh) endif From 3f1fd6e2c1073efa6e46a3b41052fdc8cb34bd77 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 2 Jul 2020 11:54:10 -0500 Subject: [PATCH 119/239] Tweaks to decrease the number of garbage candidates slightly. --- lib/fst240_decode.f90 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index d715188c5..e3d74f3ce 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -270,9 +270,6 @@ contains endif minsync=1.25 - if(iqorw.eq.2) then - minsync=1.2 - endif ! Get first approximation of candidate frequencies call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & @@ -412,7 +409,7 @@ contains ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 44) cycle !### Value ?? ### + if(nsync_qual.lt. 46) cycle !### Value ?? ### scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) @@ -559,6 +556,7 @@ contains fsig=fc_synced - 1.5*hmod*baud !write(21,'(i6,7i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & ! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg +!flush(21) call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr) goto 2002 @@ -748,10 +746,11 @@ contains ! Find candidates, using the CLEAN algorithm to remove a model of each one ! from s2() after it has been found. pval=99.99 - do while(ncand.lt.100 .and. pval.gt.minsync) + do while(ncand.lt.100) im=maxloc(s2(ia:ib)) iploc=ia+im(1)-1 !Index of CCF peak pval=s2(iploc) !Peak value + if(pval.lt.minsync) exit if(s2(iploc).gt.thresh) then !Is this a possible candidate? do i=-3,+3 !Remove 0.9 of a model CCF at k=iploc+2*hmod*i !this frequency from s2() From ee013f8687d572438975188bf9fa2de12307ca59 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 13:29:43 -0400 Subject: [PATCH 120/239] Remove an unused action. --- widgets/mainwindow.ui | 5 ----- 1 file changed, 5 deletions(-) diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 6bc4ad595..7e0fc103a 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -3489,11 +3489,6 @@ list. The list can be maintained in Settings (F2). FST240 - - - FST240-W - - FT240W From 185cf3eb4874511fe1330c5688592cb3d7131e97 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 13:30:18 -0400 Subject: [PATCH 121/239] "Also FST240W" should set iwspr=2, not 1. Change ndeep to ndepth, for consistency. --- lib/decoder.f90 | 2 +- lib/fst240_decode.f90 | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index fa50decdb..1e9245553 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -191,7 +191,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ! We're in FST240 mode ndepth=iand(params%ndepth,3) iwspr=0 - if(iand(params%ndepth,128).ne.0) iwspr=1 + if(iand(params%ndepth,128).ne.0) iwspr=2 call timer('dec240 ',0) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index e3d74f3ce..6820e8a16 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -28,7 +28,7 @@ module fst240_decode contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & - nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol,nzhsym, & + nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol,nzhsym, & emedelay,lapcqonly,napwid,mycall,hiscall,nfsplit,iwspr) use timer_module, only: timer @@ -80,6 +80,7 @@ contains this%callback => callback + print*,'AAA',iwspr,ndepth dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall @@ -216,17 +217,17 @@ contains allocate( cframe(0:160*nss-1) ) - if(ndeep.eq.3) then + if(ndepth.eq.3) then nblock=1 if(hmod.eq.1) nblock=4 ! number of block sizes to try jittermax=2 norder=3 - elseif(ndeep.eq.2) then + elseif(ndepth.eq.2) then nblock=1 if(hmod.eq.1) nblock=3 jittermax=0 norder=3 - elseif(ndeep.eq.1) then + elseif(ndepth.eq.1) then nblock=1 jittermax=0 norder=3 @@ -238,7 +239,7 @@ contains r_data(nfft1+1:nfft1+2)=0.0 call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) -! write(*,3001) iwspr,nfa,nfb,nfsplit,ndeep +! write(*,3001) iwspr,nfa,nfb,nfsplit,ndepth !3001 format('a',5i5) ! iwspr=1 !### For hardwired tests ### if(iwspr.eq.0) then @@ -436,7 +437,7 @@ contains apmag=maxval(abs(llra))*1.1 ntmax=nblock+nappasses(nQSOProgress) if(lapcqonly) ntmax=nblock+1 - if(ndeep.eq.1) ntmax=nblock + if(ndepth.eq.1) ntmax=nblock apmask=0 if(iqorw.eq.2) then ! 50-bit msgs, no ap decoding From 352b4973996864d634d5be950f4856f44039323b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 13:43:50 -0400 Subject: [PATCH 122/239] Remove a diagnostic print. --- lib/fst240_decode.f90 | 1 - widgets/mainwindow.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 6820e8a16..8fca098e6 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -80,7 +80,6 @@ contains this%callback => callback - print*,'AAA',iwspr,ndepth dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 42d839c14..398ae24fc 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5821,6 +5821,7 @@ void MainWindow::on_actionFST240_triggered() ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); + m_wideGraph->setPeriod(m_TRperiod,6912); switch_mode (Modes::FST240); m_wideGraph->setMode(m_mode); statusChanged(); From 34055d331a2e109d2b1f224b27408f53eff31cd3 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 13:48:35 -0400 Subject: [PATCH 123/239] Send TRperiod to WideGraph when entering FST240 and FST240W modes. --- widgets/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 398ae24fc..6041ca0db 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5845,6 +5845,7 @@ void MainWindow::on_actionFST240W_triggered() ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); + m_wideGraph->setPeriod(m_TRperiod,6912); switch_mode (Modes::FST240W); statusChanged(); } From 8b2b1eb3783765e244c06316802dd38a2780171f Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 14:03:00 -0400 Subject: [PATCH 124/239] FST240W should always set RxFreq=1500 and FTol=100. --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6041ca0db..ef865efc8 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5846,6 +5846,8 @@ void MainWindow::on_actionFST240W_triggered() m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setPeriod(m_TRperiod,6912); + ui->sbFtol->setValue(100); + ui->RxFreqSpinBox->setValue(1500); switch_mode (Modes::FST240W); statusChanged(); } From 1a82b9b24d7a129cd36d99929424af6ee700cabb Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 14:11:35 -0400 Subject: [PATCH 125/239] Change the label for decoded text panel in FST240W mode. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ef865efc8..cc9805227 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -6456,7 +6456,7 @@ void MainWindow::WSPR_config(bool b) ui->logQSOButton->setVisible(!b); ui->DecodeButton->setEnabled(!b); ui->band_hopping_group_box->setVisible(true); - if(b and (m_mode!="Echo")) { + if(b and m_mode!="Echo" and m_mode!="FST240W") { QString t="UTC dB DT Freq Drift Call Grid dBm "; if(m_config.miles()) t += " mi"; if(!m_config.miles()) t += " km"; From ab2371a96b6984755c3d55199f019d8c4e1343ea Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 14:57:46 -0400 Subject: [PATCH 126/239] Correct the logic for generating "Type 2: messages in FST240W. --- widgets/mainwindow.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index cc9805227..eee58ed23 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3864,8 +3864,10 @@ void MainWindow::guiUpdate() int ichk=0; int iwspr=0; char fst240msgbits[101]; + QString wmsg; if(m_mode=="FST240W") { - ba=WSPR_message().toLatin1(); + wmsg=WSPR_message(); + ba=wmsg.toLatin1(); ba2msg(ba,message); } genfst240_(message,&ichk,msgsent,const_cast (fst240msgbits), @@ -9091,7 +9093,8 @@ QString MainWindow::WSPR_message() } else { msg1=m_config.my_callsign() + sdBm; } - msg0="<" + m_config.my_callsign() + "> " + m_config.my_grid()+ sdBm; + msg0="<" + m_config.my_callsign() + "> " + m_config.my_grid(); + if(m_mode=="WSPR") msg0 += sdBm; if(m_tx==0) msg2=msg0; if(m_tx==1) msg2=msg1; } else { From 7fb7e512834e0637202aeda2981a0043ac0f99a1 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 2 Jul 2020 14:48:11 -0500 Subject: [PATCH 127/239] Use N=1,2,3,4 for now. --- lib/fst240/get_fst240_bitmetrics.f90 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst240/get_fst240_bitmetrics.f90 index 60804cba7..49f46f411 100644 --- a/lib/fst240/get_fst240_bitmetrics.f90 +++ b/lib/fst240/get_fst240_bitmetrics.f90 @@ -87,8 +87,10 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols if(nseq.eq.1) nsym=1 if(nseq.eq.2) nsym=2 - if(nseq.eq.3) nsym=4 - if(nseq.eq.4) nsym=8 + if(nseq.eq.3) nsym=3 + if(nseq.eq.4) nsym=4 +! if(nseq.eq.3) nsym=4 +! if(nseq.eq.4) nsym=8 nt=4**nsym do ks=1,NN-nsym+1,nsym s2=0 @@ -105,6 +107,7 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) ipt=1+(ks-1)*2 if(nsym.eq.1) ibmax=1 if(nsym.eq.2) ibmax=3 + if(nsym.eq.3) ibmax=5 if(nsym.eq.4) ibmax=7 if(nsym.eq.8) ibmax=15 do ib=0,ibmax From 9f3bb0fbb78b480be0a0c73192e779326fc40aaa Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 16:20:18 -0400 Subject: [PATCH 128/239] Show option "Also FST240W" only in FST240 mode. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index eee58ed23..3c720f875 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -6442,7 +6442,7 @@ void MainWindow::switch_mode (Mode mode) ui->label_6->setVisible(false); ui->label_7->setVisible(false); } - ui->actionAlso_FST240W->setVisible(m_mode.startsWith("FST240")); + ui->actionAlso_FST240W->setVisible(m_mode=="FST240"); } void MainWindow::WSPR_config(bool b) From 5637b229a08cbac10f8f3f980466d299819484b7 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 2 Jul 2020 16:54:16 -0400 Subject: [PATCH 129/239] Correct the logic for initializing TRperiod everywhere in FST240W mode. --- widgets/mainwindow.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 3c720f875..8e80c3e92 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5816,9 +5816,10 @@ void MainWindow::on_actionFST240_triggered() // 012345678901234567890123456789012 displayWidgets(nWidgets("111111000100111100010000000100000")); setup_status_bar (bVHF); - m_TRperiod = ui->sbTR->value (); + m_TRperiod = ui->sbTR->value(); ui->sbTR->setMinimum(15); ui->sbTR->setMaximum(300); + m_TRperiod = ui->sbTR->value(); on_sbTR_valueChanged(ui->sbTR->value()); ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); @@ -5842,8 +5843,13 @@ void MainWindow::on_actionFST240W_triggered() setup_status_bar (bVHF); m_TRperiod = ui->sbTR_FST240W->value (); ui->band_hopping_group_box->setVisible(false); + int ntr=m_TRperiod; ui->sbTR_FST240W->setMinimum(15); //### 120 ?? ### ui->sbTR_FST240W->setMaximum(300); + ui->sbTR_FST240W->setValue(120); //### Why is all this necessary? ### + ui->sbTR_FST240W->setValue(300); + ui->sbTR_FST240W->setValue(ntr); + m_TRperiod = ui->sbTR_FST240W->value(); ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); From b9e92c416f2bcb39148a65439bc217419ef44920 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 09:48:01 -0400 Subject: [PATCH 130/239] Implement round-robin scheduling for FST240W mode. --- widgets/mainwindow.cpp | 16 ++++++++++++++-- widgets/mainwindow.ui | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 8e80c3e92..7abe31420 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4078,7 +4078,7 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { -// qDebug() << "onesec" << m_mode; +// qDebug() << "onesec" << ui->RoundRobin->currentText(); m_currentBand=m_config.bands()->find(m_freqNominal); if( SpecOp::HOUND == m_config.special_op_id() ) { qint32 tHound=QDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn; @@ -5844,7 +5844,7 @@ void MainWindow::on_actionFST240W_triggered() m_TRperiod = ui->sbTR_FST240W->value (); ui->band_hopping_group_box->setVisible(false); int ntr=m_TRperiod; - ui->sbTR_FST240W->setMinimum(15); //### 120 ?? ### + ui->sbTR_FST240W->setMinimum(15); ui->sbTR_FST240W->setMaximum(300); ui->sbTR_FST240W->setValue(120); //### Why is all this necessary? ### ui->sbTR_FST240W->setValue(300); @@ -7899,6 +7899,18 @@ void MainWindow::on_pbTxNext_clicked(bool b) void MainWindow::WSPR_scheduling () { + QString t=ui->RoundRobin->currentText(); + if(m_mode=="FST240W" and t!="Random") { + int i=t.left(1).toInt(); + int n=t.right(1).toInt(); + + qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000; + int nsec=ms/1000; + int ntr=m_TRperiod; + int j=(nsec % (n*ntr))/ntr + 1; + m_WSPR_tx_next=(i==j); + return; + } m_WSPR_tx_next = false; if (m_config.is_transceiver_online () // need working rig control for hopping && !m_config.is_dummy_rig () diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 7e0fc103a..31bdefcc4 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2631,6 +2631,43 @@ list. The list can be maintained in Settings (F2). + + + + 0 + + + + Random + + + + + 1/2 + + + + + 2/2 + + + + + 1/3 + + + + + 2/3 + + + + + 3/3 + + + + @@ -2876,7 +2913,6 @@ list. The list can be maintained in Settings (F2). - From f9e9a4e1ec4e86caf1638e53c4c33270cff412dd Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 09:58:52 -0400 Subject: [PATCH 131/239] Don't let mouse-click on WindGraph move frequencies in FST240W mode. --- widgets/plotter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 41bf173fe..160f55b10 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -697,7 +697,7 @@ int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq void CPlotter::mouseReleaseEvent (QMouseEvent * event) { - if (Qt::LeftButton == event->button ()) { + if (Qt::LeftButton == event->button () and m_mode!="FST240W") { int x=event->x(); if(x<0) x=0; if(x>m_Size.width()) x=m_Size.width(); From 15014685acbca0652001dd731c485e58d275216b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 10:05:16 -0400 Subject: [PATCH 132/239] Round-robin control should be visible only in FST240W mode. --- widgets/mainwindow.cpp | 1 + widgets/mainwindow.ui | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 7abe31420..b321cf268 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -6464,6 +6464,7 @@ void MainWindow::WSPR_config(bool b) ui->logQSOButton->setVisible(!b); ui->DecodeButton->setEnabled(!b); ui->band_hopping_group_box->setVisible(true); + ui->RoundRobin->setVisible(b and (m_mode=="FST240W")); if(b and m_mode!="Echo" and m_mode!="FST240W") { QString t="UTC dB DT Freq Drift Call Grid dBm "; if(m_config.miles()) t += " mi"; diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 31bdefcc4..c66488293 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2697,7 +2697,7 @@ list. The list can be maintained in Settings (F2). 6 digit locators cause 2 different messages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. - Prefer type 1 messages + Prefer Type 1 messages true From cbca2f2d8099fd2ccbc9e1a41898c38a2d4eeb04 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 10:06:52 -0400 Subject: [PATCH 133/239] No band-hopping in FST240W mode. --- widgets/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b321cf268..d7201d286 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5842,6 +5842,7 @@ void MainWindow::on_actionFST240W_triggered() bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); m_TRperiod = ui->sbTR_FST240W->value (); + ui->band_hopping_group_box->setChecked(false); ui->band_hopping_group_box->setVisible(false); int ntr=m_TRperiod; ui->sbTR_FST240W->setMinimum(15); From 4a0b7b3a1d4769ea3eb601feb864a860f15beb60 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 12:01:26 -0400 Subject: [PATCH 134/239] Fix the "FST240W Type 2" and "FST240W Type 3" messages. --- lib/77bit/packjt77.f90 | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index c064f7cea..b3b1a83ea 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -203,7 +203,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) integer ntel(3) character*77 c77 character*37 msg - character*13 call_1,call_2,call_3 + character*13 call_1,call_2,call_3,call_1a character*13 mycall13_0,dxcall13_0 character*11 c11 character*3 crpt,cntx,cpfx @@ -350,11 +350,11 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) msg=adjustl(msg) else if(i3.eq.0 .and. n3.eq.6) then - read(c77(50:50),'(b1)') j2a - j2b=0 - if(j2a.eq.0) read(c77(49:49),'(b1)') j2b - j2=2*j2a+j2b - if(j2.eq.0) then + read(c77(49:50),'(2b1)') j2a,j2b + itype=2 + if(j2b.eq.0 .and. j2a.eq.0) itype=1 + if(j2b.eq.0 .and. j2a.eq.1) itype=3 + if(itype.eq.1) then ! WSPR Type 1 read(c77,2010) n28,igrid4,idbm 2010 format(b28.28,b15.15,b5.5) @@ -364,18 +364,10 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) call to_grid4(igrid4,grid4) write(crpt,'(i3)') idbm msg=trim(call_1)//' '//grid4//' '//trim(adjustl(crpt)) + call save_hash_call(call_1,n10,n12,n22) !### Is this OK here? ### - else if(j2.eq.1) then + else if(itype.eq.2) then ! WSPR Type 2 - read(c77,2030) n28,igrid6 -2030 format(b22.22,b25.25) - call unpack28(n28,call_1,unpk28_success) - if(.not.unpk28_success) unpk77_success=.false. - call to_grid6(igrid6,grid6) - msg=trim(call_1)//' '//grid6 - - else if(j2.eq.2) then -! WSPR Type 3 read(c77,2020) n28,npfx,idbm 2020 format(b28.28,b16.16,b5.5) idbm=nint(idbm*10.0/3.0) @@ -391,6 +383,8 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) if(npfx.eq.0) exit enddo msg=trim(adjustl(cpfx))//'/'//trim(call_1)//' '//trim(adjustl(crpt)) + call_1a=trim(adjustl(cpfx))//'/'//trim(call_1) + call save_hash_call(call_1a,n10,n12,n22) !### Is this OK here? ### else ! Suffix npfx=npfx-nzzz @@ -409,7 +403,20 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) return endif msg=trim(call_1)//'/'//trim(adjustl(cpfx))//' '//trim(adjustl(crpt)) + call_1a=trim(call_1)//'/'//trim(adjustl(cpfx)) + call save_hash_call(call_1a,n10,n12,n22) !### Is this OK here? ### endif + + else if(itype.eq.3) then +! WSPR Type 3 + read(c77,2030) n22,igrid6 +2030 format(b22.22,b25.25) + n28=n22+2063592 + call unpack28(n28,call_1,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. + call to_grid6(igrid6,grid6) + msg=trim(call_1)//' '//grid6 + endif @@ -1032,6 +1039,7 @@ subroutine pack77_06(nwords,w,i3,n3,c77) i3=0 n3=6 call pack28(w(1),n28) + n22=n28-2063592 k1=(ichar(grid6(1:1))-ichar('A'))*18*10*10*24*24 k2=(ichar(grid6(2:2))-ichar('A'))*10*10*24*24 k3=(ichar(grid6(3:3))-ichar('0'))*10*24*24 @@ -1039,7 +1047,7 @@ subroutine pack77_06(nwords,w,i3,n3,c77) k5=(ichar(grid6(5:5))-ichar('A'))*24 k6=(ichar(grid6(6:6))-ichar('A')) igrid6=k1+k2+k3+k4+k5+k6 - write(c77,1030) n28,igrid6,2,0,n3,i3 + write(c77,1030) n22,igrid6,2,0,n3,i3 1030 format(b22.22,b25.25,b3.3,b21.21,2b3.3) endif From d4bf73df84c890a11715b2d7d8683acfbbb6941c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 14:17:13 -0400 Subject: [PATCH 135/239] Minor cleanup of RoundRobin control. --- widgets/mainwindow.cpp | 9 ++++++++- widgets/mainwindow.h | 1 + widgets/mainwindow.ui | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index d7201d286..48767a8f4 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5574,6 +5574,12 @@ void MainWindow::on_tx6_editingFinished() //tx6 edited msgtype(t, ui->tx6); } +void MainWindow::on_RoundRobin_currentTextChanged(QString text) +{ + ui->sbTxPercent->setEnabled(text=="Random"); +} + + void MainWindow::on_dxCallEntry_textChanged (QString const& call) { m_hisCall = call; @@ -6465,7 +6471,8 @@ void MainWindow::WSPR_config(bool b) ui->logQSOButton->setVisible(!b); ui->DecodeButton->setEnabled(!b); ui->band_hopping_group_box->setVisible(true); - ui->RoundRobin->setVisible(b and (m_mode=="FST240W")); + ui->RoundRobin->setVisible(m_mode=="FST240W"); + ui->RoundRobin->lineEdit()->setAlignment(Qt::AlignCenter); if(b and m_mode!="Echo" and m_mode!="FST240W") { QString t="UTC dB DT Freq Drift Call Grid dBm "; if(m_config.miles()) t += " mi"; diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 646486fb5..c2b73bf23 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -316,6 +316,7 @@ private slots: void not_GA_warning_message (); void checkMSK144ContestType(); void on_pbBestSP_clicked(); + void on_RoundRobin_currentTextChanged(QString text); int setTxMsg(int n); bool stdCall(QString const& w); void remote_configure (QString const& mode, quint32 frequency_tolerance, QString const& submode diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index c66488293..91d8e95ba 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2633,6 +2633,9 @@ list. The list can be maintained in Settings (F2). + + true + 0 From bdfca55d1653c3b7aa537a8161397b277f5b09df Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 18:46:58 -0400 Subject: [PATCH 136/239] Fix two remaining references to FST280. Should be FST240. --- models/Modes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/Modes.cpp b/models/Modes.cpp index 1b1febfa8..d337fafd5 100644 --- a/models/Modes.cpp +++ b/models/Modes.cpp @@ -25,8 +25,8 @@ namespace "FreqCal", "FT8", "FT4", - "FST280", - "FST280W" + "FST240", + "FST240W" }; std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]); } From 5e4f77c6a921a18243eb8317043ebe9bb2cd601c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 18:55:29 -0400 Subject: [PATCH 137/239] Set initial default frequencies for FST240W to WSPR freq +200 Hz. --- models/FrequencyList.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index 056950611..d91fbab27 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -46,7 +46,7 @@ namespace {20000000, Modes::FreqCal, IARURegions::ALL}, {136000, Modes::WSPR, IARURegions::ALL}, - {136000, Modes::FST240W, IARURegions::ALL}, + {136200, Modes::FST240W, IARURegions::ALL}, {136130, Modes::JT65, IARURegions::ALL}, {136130, Modes::JT9, IARURegions::ALL}, {136130, Modes::FST240, IARURegions::ALL}, @@ -55,7 +55,7 @@ namespace {474200, Modes::JT9, IARURegions::ALL}, {474200, Modes::FST240, IARURegions::ALL}, {474200, Modes::WSPR, IARURegions::ALL}, - {474200, Modes::FST240W, IARURegions::ALL}, + {474400, Modes::FST240W, IARURegions::ALL}, {1836600, Modes::WSPR, IARURegions::ALL}, {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations @@ -95,6 +95,7 @@ namespace {3572000, Modes::FST240, IARURegions::ALL}, {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out + {3568800, Modes::FST240W, IARURegions::ALL}, {3575000, Modes::FT4, IARURegions::ALL}, // provisional {3568000, Modes::FT4, IARURegions::R3}, // provisional @@ -130,6 +131,7 @@ namespace // 7110 LSB EMCOMM // {7038600, Modes::WSPR, IARURegions::ALL}, + {7038800, Modes::FST240W, IARURegions::ALL}, {7074000, Modes::FT8, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL}, @@ -167,6 +169,7 @@ namespace {10136000, Modes::FT8, IARURegions::ALL}, {10138000, Modes::JT65, IARURegions::ALL}, {10138700, Modes::WSPR, IARURegions::ALL}, + {10138900, Modes::FST240W, IARURegions::ALL}, {10140000, Modes::JT9, IARURegions::ALL}, {10140000, Modes::FST240, IARURegions::ALL}, {10140000, Modes::FT4, IARURegions::ALL}, // provisional @@ -209,6 +212,7 @@ namespace // 14106.5 OLIVIA 1000 (main QRG) // {14095600, Modes::WSPR, IARURegions::ALL}, + {14095800, Modes::FST240W, IARURegions::ALL}, {14074000, Modes::FT8, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL}, @@ -248,12 +252,14 @@ namespace {18104000, Modes::FST240, IARURegions::ALL}, {18104000, Modes::FT4, IARURegions::ALL}, // provisional {18104600, Modes::WSPR, IARURegions::ALL}, - + {18104800, Modes::FST240W, IARURegions::ALL}, + {21074000, Modes::FT8, IARURegions::ALL}, {21076000, Modes::JT65, IARURegions::ALL}, {21078000, Modes::JT9, IARURegions::ALL}, {21078000, Modes::FST240, IARURegions::ALL}, {21094600, Modes::WSPR, IARURegions::ALL}, + {21094800, Modes::FST240W, IARURegions::ALL}, {21140000, Modes::FT4, IARURegions::ALL}, {24915000, Modes::FT8, IARURegions::ALL}, @@ -262,12 +268,14 @@ namespace {24919000, Modes::FST240, IARURegions::ALL}, {24919000, Modes::FT4, IARURegions::ALL}, // provisional {24924600, Modes::WSPR, IARURegions::ALL}, - + {24924800, Modes::FST240W, IARURegions::ALL}, + {28074000, Modes::FT8, IARURegions::ALL}, {28076000, Modes::JT65, IARURegions::ALL}, {28078000, Modes::JT9, IARURegions::ALL}, {28078000, Modes::FST240, IARURegions::ALL}, {28124600, Modes::WSPR, IARURegions::ALL}, + {28124800, Modes::FST240W, IARURegions::ALL}, {28180000, Modes::FT4, IARURegions::ALL}, {50200000, Modes::Echo, IARURegions::ALL}, @@ -278,6 +286,8 @@ namespace {50260000, Modes::MSK144, IARURegions::R3}, {50293000, Modes::WSPR, IARURegions::R2}, {50293000, Modes::WSPR, IARURegions::R3}, + {50293200, Modes::FST240W, IARURegions::R2}, + {50293200, Modes::FST240W, IARURegions::R3}, {50310000, Modes::JT65, IARURegions::ALL}, {50312000, Modes::JT9, IARURegions::ALL}, {50312000, Modes::FST240, IARURegions::ALL}, @@ -289,6 +299,7 @@ namespace {70102000, Modes::JT65, IARURegions::R1}, {70104000, Modes::JT9, IARURegions::R1}, {70091000, Modes::WSPR, IARURegions::R1}, + {70091200, Modes::FST240W, IARURegions::R2}, {70230000, Modes::MSK144, IARURegions::R1}, {144120000, Modes::JT65, IARURegions::ALL}, @@ -298,6 +309,7 @@ namespace {144360000, Modes::MSK144, IARURegions::R1}, {144150000, Modes::MSK144, IARURegions::R2}, {144489000, Modes::WSPR, IARURegions::ALL}, + {144489200, Modes::FST240W, IARURegions::R2}, {144120000, Modes::QRA64, IARURegions::ALL}, {222065000, Modes::Echo, IARURegions::R2}, From 24113a5c05d6dfd1d8a61d17ac1cac2849c7924d Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 3 Jul 2020 18:59:00 -0400 Subject: [PATCH 138/239] One more frequency for FST240W. --- models/FrequencyList.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index d91fbab27..74bc0ef64 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -58,6 +58,7 @@ namespace {474400, Modes::FST240W, IARURegions::ALL}, {1836600, Modes::WSPR, IARURegions::ALL}, + {1836800, Modes::FST240W, IARURegions::ALL}, {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations {1839000, Modes::JT9, IARURegions::ALL}, {1839000, Modes::FST240, IARURegions::ALL}, From c176572ec00d19c487813035d8a38cb4c621beaa Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 4 Jul 2020 09:15:57 -0500 Subject: [PATCH 139/239] Add options for sub-symbol integration for sync and symbol estimation. --- CMakeLists.txt | 1 + lib/fst240/get_fst240_bitmetrics.f90 | 13 ++- lib/fst240/get_fst240_bitmetrics2.f90 | 131 +++++++++++++++++++++++++ lib/fst240_decode.f90 | 136 +++++++++++++++----------- 4 files changed, 218 insertions(+), 63 deletions(-) create mode 100644 lib/fst240/get_fst240_bitmetrics2.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 99e160a4e..911425a5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -604,6 +604,7 @@ set (wsjt_FSRCS lib/fst240/gen_fst240wave.f90 lib/fst240/genfst240.f90 lib/fst240/get_fst240_bitmetrics.f90 + lib/fst240/get_fst240_bitmetrics2.f90 lib/fst240/ldpcsim240_101.f90 lib/fst240/ldpcsim240_74.f90 lib/fst240/osd240_101.f90 diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst240/get_fst240_bitmetrics.f90 index 49f46f411..e82d73c99 100644 --- a/lib/fst240/get_fst240_bitmetrics.f90 +++ b/lib/fst240/get_fst240_bitmetrics.f90 @@ -1,4 +1,4 @@ -subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) +subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) include 'fst240_params.f90' complex cd(0:NN*nss-1) @@ -87,10 +87,13 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,bitmetrics,s4,badsync) do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols if(nseq.eq.1) nsym=1 if(nseq.eq.2) nsym=2 - if(nseq.eq.3) nsym=3 - if(nseq.eq.4) nsym=4 -! if(nseq.eq.3) nsym=4 -! if(nseq.eq.4) nsym=8 + if(nhicoh.eq.0) then + if(nseq.eq.3) nsym=3 + if(nseq.eq.4) nsym=4 + else + if(nseq.eq.3) nsym=4 + if(nseq.eq.4) nsym=8 + endif nt=4**nsym do ks=1,NN-nsym+1,nsym s2=0 diff --git a/lib/fst240/get_fst240_bitmetrics2.f90 b/lib/fst240/get_fst240_bitmetrics2.f90 new file mode 100644 index 000000000..7b86841ba --- /dev/null +++ b/lib/fst240/get_fst240_bitmetrics2.f90 @@ -0,0 +1,131 @@ +subroutine get_fst240_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) + + include 'fst240_params.f90' + complex cd(0:NN*nss-1) + complex csymb(nss) + complex, allocatable, save :: c1(:,:) ! ideal waveforms, 4 tones + complex cp(0:3) ! accumulated phase shift over symbol types 0:3 + complex csum,cterm + integer isyncword1(0:7),isyncword2(0:7) + integer graymap(0:3) + integer ip(1) + integer hmod + logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits + logical first + logical badsync + real bitmetrics(2*NN,4) + real s2(0:65535) + real s4(0:3,NN,4),s4hmod(0:3,NN) + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ + data graymap/0,1,3,2/ + data first/.true./,nss0/-1/ + save first,one,cp,nss0 + + if(nss.ne.nss0 .and. allocated(c1)) deallocate(c1) + if(first .or. nss.ne.nss0) then + allocate(c1(nss,0:3)) + one=.false. + do i=0,65535 + do j=0,15 + if(iand(i,2**j).ne.0) one(i,j)=.true. + enddo + enddo + twopi=8.0*atan(1.0) + dphi=twopi*hmod/nss + do itone=0,3 + dp=(itone-1.5)*dphi + phi=0.0 + do j=1,nss + c1(j,itone)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dp,twopi) + enddo + cp(itone)=cmplx(cos(phi),sin(phi)) + enddo + first=.false. + endif + + do k=1,NN + i1=(k-1)*NSS + csymb=cd(i1:i1+NSS-1) + do itone=0,3 + s4(itone,k,1)=abs(sum(csymb*conjg(c1(:,itone)))) + s4(itone,k,2)=abs(sum(csymb( 1:nss/2)*conjg(c1( 1:nss/2,itone)))) + & + abs(sum(csymb(nss/2+1: nss)*conjg(c1(nss/2+1: nss,itone)))) + s4(itone,k,3)=abs(sum(csymb( 1: nss/4)*conjg(c1( 1: nss/4,itone)))) + & + abs(sum(csymb( nss/4+1: nss/2)*conjg(c1( nss/4+1: nss/2,itone)))) + & + abs(sum(csymb( nss/2+1:3*nss/4)*conjg(c1( nss/2+1:3*nss/4,itone)))) + & + abs(sum(csymb(3*nss/4+1: nss)*conjg(c1(3*nss/4+1: nss,itone)))) + s4(itone,k,4)=abs(sum(csymb( 1: nss/8)*conjg(c1( 1: nss/8,itone)))) + & + abs(sum(csymb( nss/8+1: nss/4)*conjg(c1( nss/8+1: nss/4,itone)))) + & + abs(sum(csymb( nss/4+1:3*nss/8)*conjg(c1( nss/4+1:3*nss/8,itone)))) + & + abs(sum(csymb(3*nss/8+1: nss/2)*conjg(c1(3*nss/8+1: nss/2,itone)))) + & + abs(sum(csymb( nss/2+1:5*nss/8)*conjg(c1( nss/2+1:5*nss/8,itone)))) + & + abs(sum(csymb(5*nss/8+1:3*nss/4)*conjg(c1(5*nss/8+1:3*nss/4,itone)))) + & + abs(sum(csymb(3*nss/4+1:7*nss/8)*conjg(c1(3*nss/4+1:7*nss/8,itone)))) + & + abs(sum(csymb(7*nss/8+1: nss)*conjg(c1(7*nss/8+1: nss,itone)))) + + enddo + enddo + +! Sync quality check + is1=0 + is2=0 + is3=0 + is4=0 + is5=0 + badsync=.false. + ibmax=0 + + is1=0; is2=0; is3=0; is4=0; is5=0 + do k=1,8 + ip=maxloc(s4(:,k,1)) + if(isyncword1(k-1).eq.(ip(1)-1)) is1=is1+1 + ip=maxloc(s4(:,k+38,1)) + if(isyncword2(k-1).eq.(ip(1)-1)) is2=is2+1 + ip=maxloc(s4(:,k+76,1)) + if(isyncword1(k-1).eq.(ip(1)-1)) is3=is3+1 + ip=maxloc(s4(:,k+114,1)) + if(isyncword2(k-1).eq.(ip(1)-1)) is4=is4+1 + ip=maxloc(s4(:,k+152,1)) + if(isyncword1(k-1).eq.(ip(1)-1)) is5=is5+1 + enddo + nsync=is1+is2+is3+is4+is5 !Number of correct hard sync symbols, 0-40 + badsync=.false. + + if(nsync .lt. 16) then + badsync=.true. + return + endif + + bitmetrics=0.0 + do nsub=1,nsizes + do ks=1,NN + s2=0 + do i=0,3 + s2(i)=s4(graymap(i),ks,nsub) + enddo + ipt=1+(ks-1)*2 + ibmax=1 + do ib=0,ibmax + bm=maxval(s2(0:3),one(0:3,ibmax-ib)) - & + maxval(s2(0:3),.not.one(0:3,ibmax-ib)) + if(ipt+ib.gt.2*NN) cycle + bitmetrics(ipt+ib,nsub)=bm + enddo + enddo + enddo + + call normalizebmet(bitmetrics(:,1),2*NN) + call normalizebmet(bitmetrics(:,2),2*NN) + call normalizebmet(bitmetrics(:,3),2*NN) + call normalizebmet(bitmetrics(:,4),2*NN) + +! Return the s4 array corresponding to N=1/hmod. Will be used for SNR calculation + if(hmod.eq.1) s4hmod(:,:)=s4(:,:,1) + if(hmod.eq.2) s4hmod(:,:)=s4(:,:,2) + if(hmod.eq.4) s4hmod(:,:)=s4(:,:,3) + if(hmod.eq.8) s4hmod(:,:)=s4(:,:,4) + return + +end subroutine get_fst240_bitmetrics2 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 8fca098e6..00dda3882 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -83,6 +83,8 @@ contains dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall + fMHz=10.0 + if(first) then mcq=2*mod(mcq+rvec(1:29),2)-1 mrrr=2*mod(mrrr+rvec(59:77),2)-1 @@ -217,7 +219,7 @@ contains if(ndepth.eq.3) then - nblock=1 + nblock=4 if(hmod.eq.1) nblock=4 ! number of block sizes to try jittermax=2 norder=3 @@ -252,6 +254,20 @@ contains itype2=2 endif + if(hmod.eq.1) then + if(fMHz.lt.2.0) then + nsyncoh=8 ! Use N=8 for sync + nhicoh=1 ! Use N=1,2,4,8 for symbol estimation + else + nsyncoh=4 ! Use N=4 for sync + nhicoh=0 ! Use N=1,2,3,4 for symbol estimation + endif + else + if(hmod.eq.2) nsyncoh=1 + if(hmod.eq.4) nsyncoh=1 + if(hmod.eq.8) nsyncoh=1 + endif + do iqorw=itype1,itype2 ! iqorw=1 for QSO mode and iqorw=2 for wspr-type messages if( iwspr.lt.2 ) then if( single_decode ) then @@ -278,10 +294,8 @@ contains ndecodes=0 decodes=' ' - isbest1=0 - isbest8=0 - fc21=0. - fc28=0. + isbest=0 + fc2=0. do icand=1,ncand fc0=candidates(icand,1) detmet=candidates(icand,2) @@ -308,47 +322,29 @@ contains ifhw=12 df=.1*baud else if(isync.eq.1) then - fc1=fc21 - if(hmod.eq.1) fc1=fc28 - is0=isbest1 - if(hmod.eq.1) is0=isbest8 + fc1=fc2 + is0=isbest ishw=4*hmod isst=1*hmod ifhw=7 df=.02*baud endif - smax1=0.0 - smax8=0.0 + smax=0.0 do if=-ifhw,ifhw fc=fc1+df*if do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) - call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) - if(sync8.gt.smax8) then - fc28=fc - isbest8=istart - smax8=sync8 - endif - if(sync1.gt.smax1) then - fc21=fc - isbest1=istart - smax1=sync1 + call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss,fs2,sync) + if(sync.gt.smax) then + fc2=fc + isbest=istart + smax=sync endif enddo enddo enddo call timer('sync240 ',1) - if(smax8/smax1 .lt. 0.65 ) then - fc2=fc21 - isbest=isbest1 - njitter=2 - else - fc2=fc28 - isbest=isbest8 - njitter=2 - endif fc_synced = fc0 + fc2 dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 candidates(icand,3)=fc_synced @@ -387,6 +383,7 @@ contains fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 + if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) @@ -398,7 +395,11 @@ contains if(is0.lt.0) cycle cframe=c2(is0:is0+160*nss-1) bitmetrics=0 - call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + if(hmod.eq.1) then + call get_fst240_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) + else + call get_fst240_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + endif if(badsync) cycle hbits=0 @@ -409,7 +410,7 @@ contains ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 46) cycle !### Value ?? ### +! if(nsync_qual.lt. 46) cycle !### Value ?? ### scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) @@ -529,7 +530,7 @@ contains do i=1,ndecodes if(decodes(i).eq.msg) idupe=1 enddo - if(idupe.eq.1) exit + if(idupe.eq.1) goto 2002 ndecodes=ndecodes+1 decodes(ndecodes)=msg @@ -554,9 +555,9 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud -!write(21,'(i6,7i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & -! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg -!flush(21) + write(21,'(i6,8i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & + nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg + flush(21) call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr) goto 2002 @@ -637,28 +638,47 @@ contains s4=0.0 s5=0.0 - nsec=8/ncoh - do i=1,nsec - is=(i-1)*ncoh*nss - z1=0 - if(i1+is.ge.1) then - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) - endif - z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) - z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z5=0 - if(i5+is+ncoh*nss-1.le.np) then - z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) - endif - s1=s1+abs(z1)/(8*nss) - s2=s2+abs(z2)/(8*nss) - s3=s3+abs(z3)/(8*nss) - s4=s4+abs(z4)/(8*nss) - s5=s5+abs(z5)/(8*nss) - enddo + if(ncoh.gt.0) then + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=0 + if(i1+is.ge.1) then + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z5=0 + if(i5+is+ncoh*nss-1.le.np) then + z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + s4=s4+abs(z4)/(8*nss) + s5=s5+abs(z5)/(8*nss) + enddo + else + nsub=-ncoh + nps=nss/nsub + do i=1,8 + do isub=1,nsub + is=(i-1)*nss+(isub-1)*nps + if(i1+is.ge.1) then + s1=s1+abs(sum(cd0(i1+is:i1+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + endif + s2=s2+abs(sum(cd0(i2+is:i2+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + s3=s3+abs(sum(cd0(i3+is:i3+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + s4=s4+abs(sum(cd0(i4+is:i4+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + s5=0 + if(i5+is+ncoh*nss-1.le.np) then + s5=s5+abs(sum(cd0(i5+is:i5+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + endif + enddo + enddo + endif sync = s1+s2+s3+s4+s5 - return end subroutine sync_fst240 From 3fe6fa3d7228deeed114e938f81025dc2943b5da Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 4 Jul 2020 12:57:51 -0500 Subject: [PATCH 140/239] Rough first attempt at setting minsync according to setup. --- lib/fst240_decode.f90 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 00dda3882..a0eb5ad64 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -83,7 +83,7 @@ contains dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall - fMHz=10.0 + fMHz=1.0 if(first) then mcq=2*mod(mcq+rvec(1:29),2)-1 @@ -285,7 +285,13 @@ contains fb=min(4800,nfb) endif - minsync=1.25 + if(hmod.eq.1) then + if(ntrperiod.eq.15) minsync=1.15 + if(ntrperiod.gt.15) minsync=1.20 + elseif(hmod.gt.1) then + minsync=1.5 + endif + ! Get first approximation of candidate frequencies call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & From d17bc2f97fd4af6946001e49b5ae535f8e45c390 Mon Sep 17 00:00:00 2001 From: K9AN Date: Sat, 4 Jul 2020 13:06:50 -0500 Subject: [PATCH 141/239] Comment out debug prints. --- lib/fst240_decode.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index a0eb5ad64..a0d3e4845 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -561,9 +561,9 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud - write(21,'(i6,8i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & - nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg - flush(21) +! write(21,'(i6,8i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & +! nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg +! flush(21) call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr) goto 2002 From 4de41162a34e07d9b8376a56dc160a03e6c967b3 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 6 Jul 2020 15:36:01 -0400 Subject: [PATCH 142/239] Make sure FST240W uses submode A. --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 48767a8f4..ecb0ad970 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5847,6 +5847,8 @@ void MainWindow::on_actionFST240W_triggered() displayWidgets(nWidgets("000001000000000001010000000000000")); bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); + m_nSubMode=0; + ui->sbSubmode->setValue(m_nSubMode); m_TRperiod = ui->sbTR_FST240W->value (); ui->band_hopping_group_box->setChecked(false); ui->band_hopping_group_box->setVisible(false); From adafb89769a5e515ff785340a522c56851c00a58 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 8 Jul 2020 00:10:48 +0100 Subject: [PATCH 143/239] Install FST240 simulator --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 969e17e74..15cf9aed0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1520,7 +1520,7 @@ install (TARGETS jt9 wsprd fmtave fcal fmeasure if(WSJT_BUILD_UTILS) install (TARGETS ft8code jt65code qra64code qra64sim jt9code jt4code - msk144code + msk144code fst240sim RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime ) From aa557820d464f9536d6937284afae6af814cf448 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 8 Jul 2020 02:25:25 +0100 Subject: [PATCH 144/239] Work around gfortran v10 error message --- lib/fst240_decode.f90 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index a0d3e4845..d669ca939 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -33,6 +33,7 @@ contains use timer_module, only: timer use packjt77 + use, intrinsic :: iso_c_binding include 'fst240/fst240_params.f90' parameter (MAXCAND=100) class(fst240_decoder), intent(inout) :: this @@ -45,7 +46,8 @@ contains complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable :: r_data(:) + real, allocatable, target :: r_data(:) + complex, pointer, dimension(:) :: c_data_ptr real llr(240),llra(240),llrb(240),llrc(240),llrd(240) real candidates(100,4) real bitmetrics(320,4) @@ -212,6 +214,7 @@ contains nh1=nfft1/2 allocate( r_data(1:nfft1+2) ) + call c_f_pointer (c_loc (r_data), c_data_ptr, [(nfft1+2)/2]) ! c_data_ptr shares memory with r_data allocate( c_bigfft(0:nfft1/2) ) allocate( c2(0:nfft2-1) ) @@ -238,7 +241,7 @@ contains ! and also for downconverting/downsampling each candidate. r_data(1:nfft1)=iwave(1:nfft1) r_data(nfft1+1:nfft1+2)=0.0 - call four2a(r_data,nfft1,1,-1,0) + call four2a(c_data_ptr,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) ! write(*,3001) iwspr,nfa,nfb,nfsplit,ndepth !3001 format('a',5i5) From 114cd83376c953397fd82ecf68c858c29c9ba258 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 8 Jul 2020 11:25:07 -0400 Subject: [PATCH 145/239] Signal report range has been [-30,+99]. Not it is [-50,+50], in a backward-compatible way. --- lib/77bit/packjt77.f90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 295b70568..dc6fb0f17 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -457,7 +457,9 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) if(irpt.eq.3) msg=trim(call_1)//' '//trim(call_2)//' RR73' if(irpt.eq.4) msg=trim(call_1)//' '//trim(call_2)//' 73' if(irpt.ge.5) then - write(crpt,'(i3.2)') irpt-35 + isnr=irpt-35 + if(isnr.gt.50) isnr=isnr-101 + write(crpt,'(i3.2)') isnr if(crpt(1:1).eq.' ') crpt(1:1)='+' if(ir.eq.0) msg=trim(call_1)//' '//trim(call_2)//' '//crpt if(ir.eq.1) msg=trim(call_1)//' '//trim(call_2)//' R'//crpt @@ -1095,10 +1097,12 @@ subroutine pack77_1(nwords,w,i3,n3,c77) if(c1.eq.'+' .or. c1.eq.'-') then ir=0 read(w(nwords),*,err=900) irpt + if(irpt.ge.-50 .and. irpt.le.-31) irpt=irpt+101 irpt=irpt+35 else if(c2.eq.'R+' .or. c2.eq.'R-') then ir=1 read(w(nwords)(2:),*) irpt + if(irpt.ge.-50 .and. irpt.le.-31) irpt=irpt+101 irpt=irpt+35 else if(trim(w(nwords)).eq.'RRR') then ir=0 From 5bc2417a7ed55b584f272179713040380f98522a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 8 Jul 2020 11:34:32 -0400 Subject: [PATCH 146/239] Update User Guide to mention the new range for acceptable signal reports. --- doc/user_guide/en/protocols.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user_guide/en/protocols.adoc b/doc/user_guide/en/protocols.adoc index 625f63511..d9a7d8ada 100644 --- a/doc/user_guide/en/protocols.adoc +++ b/doc/user_guide/en/protocols.adoc @@ -38,8 +38,8 @@ FN42`, it means that s/he will listen on 50.290 and respond there to any replies.) A numerical signal report of the form `–nn` or `R–nn` can be sent in place of a grid locator. (As originally defined, numerical signal reports `nn` were required to fall between -01 -and -30 dB. Recent program versions accommodate reports between --50 and +49 dB.) A country prefix or portable suffix may be +and -30 dB. Program versions 2.3 and later accommodate reports between +-50 and +50 dB.) A country prefix or portable suffix may be attached to one of the callsigns. When this feature is used the additional information is sent in place of the grid locator or by encoding additional information into some of the 6 million available From f77b6bf71ab907730f7d98c71775e9651305d20e Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 8 Jul 2020 19:37:31 +0100 Subject: [PATCH 147/239] Only show FST240W T/R period spin box in FST240W mode --- displayWidgets.txt | 38 +++++++++++++++++++----------------- widgets/mainwindow.cpp | 44 ++++++++++++++++++++++-------------------- widgets/mainwindow.h | 1 - 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/displayWidgets.txt b/displayWidgets.txt index ae813ad48..34750cf98 100644 --- a/displayWidgets.txt +++ b/displayWidgets.txt @@ -1,25 +1,26 @@ Here are the "displayWidgets()" strings for WSJT-X modes 1 2 3 - 012345678901234567890123456789012 + 0123456789012345678901234567890123 ---------------------------------------------- -JT4 111010000000110000110000000000000 -JT4/VHF 111110010010110110111100000000000 -JT9 111010000000111000010000000000001 -JT9/VHF 111110101000111110010000000000000 -JT9+JT65 111010000001111000010000000000001 -JT65 111010000000111000010000000000001 -JT65/VHF 111110010000110110101100010000000 -QRA64 111110010110110110000000001000000 -ISCAT 100111000000000110000000000000000 -MSK144 101111110100000000010001000000000 -WSPR 000000000000000001010000000000000 -Echo 000000000000000000000010000000000 -FCal 001101000000000000000000000001000 -FT8 111010000100111000010000100110001 -FT8/VHF 111010000100111000010000100110001 -FT8/Fox 111010000100111000010000000000100 -FT8/Hound 111010000100111000010000000000110 +JT4 1110100000001100001100000000000000 +JT4/VHF 1111100100101101101111000000000000 +JT9 1110100000001110000100000000000010 +JT9/VHF 1111101010001111100100000000000000 +JT9+JT65 1110100000011110000100000000000010 +JT65 1110100000001110000100000000000010 +JT65/VHF 1111100100001101101011000100000000 +QRA64 1111100101101101100000000010000000 +ISCAT 1001110000000001100000000000000000 +MSK144 1011111101000000000100010000000000 +WSPR 0000000000000000010100000000000000 +FST240W 0000000000000000010100000000000001 +Echo 0000000000000000000000100000000000 +FCal 0011010000000000000000000000010000 +FT8 1110100001001110000100001001100010 +FT8/VHF 1110100001001110000100001001100010 +FT8/Fox 1110100001001110000100000000001000 +FT8/Hound 1110100001001110000100000000001100 ---------------------------------------------- 1 2 3 012345678901234567890123456789012 @@ -60,3 +61,4 @@ Mapping of column numbers to widgets 30. labDXped 31. cbRxAll 32. cbCQonly +33. sbTR_FST240W diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ecb0ad970..9c5e9c6bb 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -208,6 +208,7 @@ namespace // grid exact match excluding RR73 QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; auto quint32_max = std::numeric_limits::max (); + constexpr int N_WIDGETS {34}; bool message_is_73 (int type, QStringList const& msg_parts) { @@ -5792,6 +5793,7 @@ void MainWindow::displayWidgets(qint64 n) if(i==30) ui->labDXped->setVisible(b); if(i==31) ui->cbRxAll->setVisible(b); if(i==32) ui->cbCQonly->setVisible(b); + if(i==33) ui->sbTR_FST240W->setVisible(b); j=j>>1; } ui->pbBestSP->setVisible(m_mode=="FT4"); @@ -5819,8 +5821,8 @@ void MainWindow::on_actionFST240_triggered() ui->actionFST240->setChecked(true); WSPR_config(false); bool bVHF=m_config.enable_VHF_features(); -// 012345678901234567890123456789012 - displayWidgets(nWidgets("111111000100111100010000000100000")); +// 0123456789012345678901234567890123 + displayWidgets(nWidgets("1111110001001111000100000001000000")); setup_status_bar (bVHF); m_TRperiod = ui->sbTR->value(); ui->sbTR->setMinimum(15); @@ -5843,8 +5845,8 @@ void MainWindow::on_actionFST240W_triggered() m_modeTx="FST240W"; WSPR_config(true); ui->actionFST240W->setChecked(true); -// 012345678901234567890123456789012 - displayWidgets(nWidgets("000001000000000001010000000000000")); +// 0123456789012345678901234567890123 + displayWidgets(nWidgets("0000000000000000010100000000000001")); bool bVHF=m_config.enable_VHF_features(); setup_status_bar (bVHF); m_nSubMode=0; @@ -5899,7 +5901,7 @@ void MainWindow::on_actionFT4_triggered() ui->label_7->setText(tr ("Rx Frequency")); ui->label_6->setText(tr ("Band Activity")); ui->decodedTextLabel->setText( " UTC dB DT Freq " + tr ("Message")); - displayWidgets(nWidgets("111010000100111000010000000110001")); + displayWidgets(nWidgets("1110100001001110000100000001100010")); ui->txrb2->setEnabled(true); ui->txrb4->setEnabled(true); ui->txrb5->setEnabled(true); @@ -5948,7 +5950,7 @@ void MainWindow::on_actionFT8_triggered() ui->label_6->setText(tr ("Band Activity")); ui->decodedTextLabel->setText( " UTC dB DT Freq " + tr ("Message")); } - displayWidgets(nWidgets("111010000100111000010000100110001")); + displayWidgets(nWidgets("1110100001001110000100001001100010")); ui->txrb2->setEnabled(true); ui->txrb4->setEnabled(true); ui->txrb5->setEnabled(true); @@ -5966,7 +5968,7 @@ void MainWindow::on_actionFT8_triggered() ui->cbAutoSeq->setEnabled(false); ui->tabWidget->setCurrentIndex(2); ui->TxFreqSpinBox->setValue(300); - displayWidgets(nWidgets("111010000100111000010000000000100")); + displayWidgets(nWidgets("1110100001001110000100000000001000")); ui->labDXped->setText(tr ("Fox")); on_fox_log_action_triggered(); } @@ -5976,7 +5978,7 @@ void MainWindow::on_actionFT8_triggered() ui->cbAutoSeq->setEnabled(false); ui->tabWidget->setCurrentIndex(0); ui->cbHoldTxFreq->setChecked(true); - displayWidgets(nWidgets("111010000100110000010000000000110")); + displayWidgets(nWidgets("11101000010011000001000000000011000")); ui->labDXped->setText(tr ("Hound")); ui->txrb1->setChecked(true); ui->txrb2->setEnabled(false); @@ -6051,9 +6053,9 @@ void MainWindow::on_actionJT4_triggered() ui->sbSubmode->setValue(0); } if(bVHF) { - displayWidgets(nWidgets("111110010010110110111100000000000")); + displayWidgets(nWidgets("1111100100101101101111000000000000")); } else { - displayWidgets(nWidgets("111010000000110000110000000000000")); + displayWidgets(nWidgets("1110100000001100001100000000000000")); } fast_config(false); statusChanged(); @@ -6106,9 +6108,9 @@ void MainWindow::on_actionJT9_triggered() ui->label_6->setText(tr ("Band Activity")); ui->label_7->setText(tr ("Rx Frequency")); if(bVHF) { - displayWidgets(nWidgets("111110101000111110010000000000000")); + displayWidgets(nWidgets("1111101010001111100100000000000000")); } else { - displayWidgets(nWidgets("111010000000111000010000000000001")); + displayWidgets(nWidgets("1110100000001110000100000000000010")); } fast_config(m_bFastMode); ui->cbAutoSeq->setVisible(m_bFast9); @@ -6147,7 +6149,7 @@ void MainWindow::on_actionJT9_JT65_triggered() ui->label_7->setText(tr ("Rx Frequency")); ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message")); - displayWidgets(nWidgets("111010000001111000010000000000001")); + displayWidgets(nWidgets("1110100000011110000100000000000010")); fast_config(false); statusChanged(); } @@ -6195,9 +6197,9 @@ void MainWindow::on_actionJT65_triggered() ui->label_7->setText(tr ("Rx Frequency")); } if(bVHF) { - displayWidgets(nWidgets("111110010000110110101100010000000")); + displayWidgets(nWidgets("1111100100001101101011000100000000")); } else { - displayWidgets(nWidgets("111010000000111000010000000000001")); + displayWidgets(nWidgets("1110100000001110000100000000000010")); } fast_config(false); if(ui->cbShMsgs->isChecked()) { @@ -6229,7 +6231,7 @@ void MainWindow::on_actionQRA64_triggered() ui->TxFreqSpinBox->setValue(1000); QString fname {QDir::toNativeSeparators(m_config.temp_dir ().absoluteFilePath ("red.dat"))}; m_wideGraph->setRedFile(fname); - displayWidgets(nWidgets("111110010010110110000000001000000")); + displayWidgets(nWidgets("1111100100101101100000000010000000")); statusChanged(); } @@ -6265,7 +6267,7 @@ void MainWindow::on_actionISCAT_triggered() ui->sbSubmode->setMaximum(1); if(m_nSubMode==0) ui->TxFreqSpinBox->setValue(1012); if(m_nSubMode==1) ui->TxFreqSpinBox->setValue(560); - displayWidgets(nWidgets("100111000000000110000000000000000")); + displayWidgets(nWidgets("1001110000000001100000000000000000")); fast_config(true); statusChanged (); } @@ -6326,7 +6328,7 @@ void MainWindow::on_actionMSK144_triggered() ui->rptSpinBox->setValue(0); ui->rptSpinBox->setSingleStep(1); ui->sbFtol->values ({20, 50, 100, 200}); - displayWidgets(nWidgets("101111110100000000010001000010000")); + displayWidgets(nWidgets("1011111101000000000100010000100000")); fast_config(m_bFastMode); statusChanged(); @@ -6364,7 +6366,7 @@ void MainWindow::on_actionWSPR_triggered() m_bFastMode=false; m_bFast9=false; ui->TxFreqSpinBox->setValue(ui->WSPRfreqSpinBox->value()); - displayWidgets(nWidgets("000000000000000001010000000000000")); + displayWidgets(nWidgets("0000000000000000010100000000000000")); fast_config(false); statusChanged(); } @@ -6397,7 +6399,7 @@ void MainWindow::on_actionEcho_triggered() m_bFast9=false; WSPR_config(true); ui->decodedTextLabel->setText(" UTC N Level Sig DF Width Q"); - displayWidgets(nWidgets("000000000000000000000010000000000")); + displayWidgets(nWidgets("0000000000000000000000100000000000")); fast_config(false); statusChanged(); } @@ -6422,7 +6424,7 @@ void MainWindow::on_actionFreqCal_triggered() // 18:15:47 0 1 1500 1550.349 0.100 3.5 10.2 ui->decodedTextLabel->setText(" UTC Freq CAL Offset fMeas DF Level S/N"); ui->measure_check_box->setChecked (false); - displayWidgets(nWidgets("001101000000000000000000000001000")); + displayWidgets(nWidgets("0011010000000000000000000000010000")); statusChanged(); } diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index c2b73bf23..070fbbae5 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -51,7 +51,6 @@ #define NUM_FST240_SYMBOLS 160 //240/2 data + 5*8 sync #define NUM_CW_SYMBOLS 250 #define TX_SAMPLE_RATE 48000 -#define N_WIDGETS 33 #define NRING 3456000 extern int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols From 8941b70a2a8baccc97cf715b2172782b2f6b4c10 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 9 Jul 2020 14:13:23 -0500 Subject: [PATCH 148/239] Changes to improve sensitivity on overspread channels. --- lib/fst240/ldpcsim240_74.f90 | 2 +- lib/fst240_decode.f90 | 37 +++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/fst240/ldpcsim240_74.f90 b/lib/fst240/ldpcsim240_74.f90 index 78e8e6b5f..b488aa6b6 100644 --- a/lib/fst240/ldpcsim240_74.f90 +++ b/lib/fst240/ldpcsim240_74.f90 @@ -101,7 +101,7 @@ write(*,'(24i1)') msgbits(51:74) llr=2.0*rxdata/(ss*ss) apmask=0 dmin=0.0 - maxosd=2 + maxosd=0 call decode240_74(llr, Keff, maxosd, norder, apmask, message74, cw, ntype, nharderror, dmin) if(nharderror.ge.0) then n2err=0 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index a0d3e4845..73384d29e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -220,7 +220,6 @@ contains if(ndepth.eq.3) then nblock=4 - if(hmod.eq.1) nblock=4 ! number of block sizes to try jittermax=2 norder=3 elseif(ndepth.eq.2) then @@ -264,8 +263,8 @@ contains endif else if(hmod.eq.2) nsyncoh=1 - if(hmod.eq.4) nsyncoh=1 - if(hmod.eq.8) nsyncoh=1 + if(hmod.eq.4) nsyncoh=-2 + if(hmod.eq.8) nsyncoh=-4 endif do iqorw=itype1,itype2 ! iqorw=1 for QSO mode and iqorw=2 for wspr-type messages @@ -289,7 +288,7 @@ contains if(ntrperiod.eq.15) minsync=1.15 if(ntrperiod.gt.15) minsync=1.20 elseif(hmod.gt.1) then - minsync=1.5 + minsync=1.2 endif @@ -463,8 +462,13 @@ contains napwid=1.2*(4.0*baud*hmod) if(itry.gt.nblock) then - if(nblock.eq.1) llr=llra - if(nblock.gt.1) llr=llrc + llr=llra + if(nblock.gt.1) then + if(hmod.eq.1) llr=llrd + if(hmod.eq.2) llr=llrb + if(hmod.eq.4) llr=llrc + if(hmod.eq.8) llr=llrd + endif iaptype=naptypes(nQSOProgress,itry-nblock) if(lapcqonly) iaptype=1 if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall @@ -531,6 +535,7 @@ contains c77(51:77)='000000000000000000000110000' call unpack77(c77,0,msg,unpk77_success) endif +! if(unpk77_success.and.index(msg,"K9AN").ne.0) then if(unpk77_success) then idupe=0 do i=1,ndecodes @@ -561,7 +566,7 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud -! write(21,'(i6,8i6,f7.1,f9.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & +! write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & ! nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg ! flush(21) call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & @@ -671,16 +676,22 @@ contains do i=1,8 do isub=1,nsub is=(i-1)*nss+(isub-1)*nps + z1=0.0 if(i1+is.ge.1) then - s1=s1+abs(sum(cd0(i1+is:i1+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + z1=sum(cd0(i1+is:i1+is+nps-1)*conjg(csynct1(is+1:is+nps))) endif - s2=s2+abs(sum(cd0(i2+is:i2+is+nps-1)*conjg(csynct1(is+1:is+nps)))) - s3=s3+abs(sum(cd0(i3+is:i3+is+nps-1)*conjg(csynct1(is+1:is+nps)))) - s4=s4+abs(sum(cd0(i4+is:i4+is+nps-1)*conjg(csynct1(is+1:is+nps)))) - s5=0 + z2=sum(cd0(i2+is:i2+is+nps-1)*conjg(csynct2(is+1:is+nps))) + z3=sum(cd0(i3+is:i3+is+nps-1)*conjg(csynct1(is+1:is+nps))) + z4=sum(cd0(i4+is:i4+is+nps-1)*conjg(csynct2(is+1:is+nps))) + z5=0.0 if(i5+is+ncoh*nss-1.le.np) then - s5=s5+abs(sum(cd0(i5+is:i5+is+nps-1)*conjg(csynct1(is+1:is+nps)))) + z5=sum(cd0(i5+is:i5+is+nps-1)*conjg(csynct1(is+1:is+nps))) endif + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + s4=s4+abs(z4)/(8*nss) + s5=s5+abs(z5)/(8*nss) enddo enddo endif From 89985376222aa8a2d11fe1482d265557828cb6b5 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 9 Jul 2020 15:30:46 -0500 Subject: [PATCH 149/239] Clean up a couple of loose ends. --- lib/fst240_decode.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 53c29633b..981b6b60c 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -391,7 +391,6 @@ contains fc_synced=candidates(icand,3) isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 - if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) @@ -419,7 +418,6 @@ contains ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 ! if(nsync_qual.lt. 46) cycle !### Value ?? ### - scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) llra( 61:120)=bitmetrics( 93:152, 1) @@ -462,7 +460,6 @@ contains apmask=0 iaptype=0 endif - napwid=1.2*(4.0*baud*hmod) if(itry.gt.nblock) then llr=llra @@ -538,7 +535,6 @@ contains c77(51:77)='000000000000000000000110000' call unpack77(c77,0,msg,unpk77_success) endif -! if(unpk77_success.and.index(msg,"K9AN").ne.0) then if(unpk77_success) then idupe=0 do i=1,ndecodes From 3e61688229c6194f88e47e8ea103ef7e081453e9 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 11 Jul 2020 15:24:21 -0400 Subject: [PATCH 150/239] Fix the nagging 'KA1R' problem with decoding after change in TRperiod. --- lib/fst240_decode.f90 | 146 +++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index d669ca939..7fa770b3e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -46,8 +46,6 @@ contains complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable, target :: r_data(:) - complex, pointer, dimension(:) :: c_data_ptr real llr(240),llra(240),llrb(240),llrc(240),llrd(240) real candidates(100,4) real bitmetrics(320,4) @@ -121,7 +119,7 @@ contains hiscall0='' first=.false. endif - + l1=index(mycall,char(0)) if(l1.ne.0) mycall(l1:)=" " l1=index(hiscall,char(0)) @@ -213,14 +211,10 @@ contains nfft1=nfft2*ndown nh1=nfft1/2 - allocate( r_data(1:nfft1+2) ) - call c_f_pointer (c_loc (r_data), c_data_ptr, [(nfft1+2)/2]) ! c_data_ptr shares memory with r_data - allocate( c_bigfft(0:nfft1/2) ) - + allocate( c_bigfft(0:nfft1/2+1) ) allocate( c2(0:nfft2-1) ) allocate( cframe(0:160*nss-1) ) - - + if(ndepth.eq.3) then nblock=4 if(hmod.eq.1) nblock=4 ! number of block sizes to try @@ -239,13 +233,11 @@ contains ! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. - r_data(1:nfft1)=iwave(1:nfft1) - r_data(nfft1+1:nfft1+2)=0.0 - call four2a(c_data_ptr,nfft1,1,-1,0) - c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) -! write(*,3001) iwspr,nfa,nfb,nfsplit,ndepth -!3001 format('a',5i5) -! iwspr=1 !### For hardwired tests ### + do i=1,nfft1/2 + c_bigfft(i)=cmplx(float(iwave(2*i-1)),float(iwave(2*i))) + enddo + c_bigfft(nfft1/2+1)=0. + call four2a(c_bigfft,nfft1,1,-1,0) if(iwspr.eq.0) then itype1=1 itype2=1 @@ -295,10 +287,9 @@ contains minsync=1.5 endif - ! Get first approximation of candidate frequencies call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - minsync,ncand,candidates,base) + minsync,ncand,candidates,base) ndecodes=0 decodes=' ' @@ -317,41 +308,49 @@ contains call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) call timer('sync240 ',0) - do isync=0,1 - if(isync.eq.0) then - fc1=0.0 - if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s - is0=1.5*nspsec - ishw=1.5*nspsec - else ! search plus or minus 1.5 s centered on emedelay - is0=nint(emedelay*nspsec) - ishw=1.5*nspsec - endif - isst=4*hmod - ifhw=12 - df=.1*baud - else if(isync.eq.1) then - fc1=fc2 - is0=isbest - ishw=4*hmod - isst=1*hmod - ifhw=7 - df=.02*baud - endif - smax=0.0 - do if=-ifhw,ifhw - fc=fc1+df*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss,fs2,sync) - if(sync.gt.smax) then - fc2=fc - isbest=istart - smax=sync - endif - enddo + fc1=0.0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint(emedelay*nspsec) + ishw=1.5*nspsec + endif + + smax=-1.e30 + do if=-12,12 + fc=fc1 + 0.1*baud*if + do istart=max(1,is0-ishw),is0+ishw,4*hmod + call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + ntrperiod,fs2,sync) + if(sync.gt.smax) then + fc2=fc + isbest=istart + smax=sync + endif enddo enddo + + fc1=fc2 + is0=isbest + ishw=4*hmod + isst=1*hmod + + smax=0.0 + do if=-7,7 + fc=fc1 + 0.02*baud*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + ntrperiod,fs2,sync) + if(sync.gt.smax) then + fc2=fc + isbest=istart + smax=sync + endif + enddo + enddo + call timer('sync240 ',1) fc_synced = fc0 + fc2 @@ -579,29 +578,29 @@ contains return end subroutine decode - subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,ntr,fs,sync) ! Compute sync power for a complex, downsampled FST240 signal. + use timer_module, only: timer include 'fst240/fst240_params.f90' complex cd0(0:np-1) - complex, allocatable, save :: csync1(:),csync2(:) - complex, allocatable, save :: csynct1(:),csynct2(:) - complex ctwk(8*nss) + complex csync1,csync2,csynct1,csynct2 + complex ctwk(3200) complex z1,z2,z3,z4,z5 - logical first integer hmod,isyncword1(0:7),isyncword2(0:7) real f0save + common/sync240com/csync1(3200),csync2(3200),csynct1(3200),csynct2(3200) data isyncword1/0,1,3,2,1,0,2,3/ data isyncword2/2,3,1,0,3,2,0,1/ - data first/.true./,f0save/-99.9/,nss0/-1/ - save first,twopi,dt,fac,f0save,nss0 + data f0save/-99.9/,nss0/-1/,ntr0/-1/ + save twopi,dt,fac,f0save,nss0,ntr0 + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power - if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) - if(first .or. nss.ne.nss0) then - allocate( csync1(8*nss), csync2(8*nss) ) - allocate( csynct1(8*nss), csynct2(8*nss) ) + nz=8*nss + call timer('sync240a',0) + if(nss.ne.nss0 .or. ntr.ne.ntr0) then twopi=8.0*atan(1.0) dt=1/fs k=1 @@ -618,22 +617,25 @@ contains k=k+1 enddo enddo - first=.false. - nss0=nss fac=1.0/(8.0*nss) + nss0=nss + ntr0=ntr + f0save=-1.e30 endif if(f0.ne.f0save) then dphi=twopi*f0*dt phi=0.0 - do i=1,8*nss + do i=1,nz ctwk(i)=cmplx(cos(phi),sin(phi)) phi=mod(phi+dphi,twopi) enddo - csynct1=ctwk*csync1 - csynct2=ctwk*csync2 + csynct1(1:nz)=ctwk(1:nz)*csync1(1:nz) + csynct2(1:nz)=ctwk(1:nz)*csync2(1:nz) f0save=f0 + nss0=nss endif + call timer('sync240a',1) i1=i0 !Costas arrays i2=i0+38*nss @@ -662,11 +664,11 @@ contains if(i5+is+ncoh*nss-1.le.np) then z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) endif - s1=s1+abs(z1)/(8*nss) - s2=s2+abs(z2)/(8*nss) - s3=s3+abs(z3)/(8*nss) - s4=s4+abs(z4)/(8*nss) - s5=s5+abs(z5)/(8*nss) + s1=s1+abs(z1)/nz + s2=s2+abs(z2)/nz + s3=s3+abs(z3)/nz + s4=s4+abs(z4)/nz + s5=s5+abs(z5)/nz enddo else nsub=-ncoh @@ -718,7 +720,7 @@ contains subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & minsync,ncand,candidates,base) - complex c_bigfft(0:nfft1/2) !Full length FFT of raw data + complex c_bigfft(0:nfft1/2+1) !Full length FFT of raw data integer hmod !Modulation index (submode) integer im(1) !For maxloc real candidates(100,4) !Candidate list From 4cb902a4cc26b5557a092464f716a20c0676d969 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 11 Jul 2020 16:39:31 -0500 Subject: [PATCH 151/239] Try to get c_bigfft sorted out. --- lib/fst240_decode.f90 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index ef0d6f40c..b57cc401d 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -211,7 +211,7 @@ contains nfft1=nfft2*ndown nh1=nfft1/2 - allocate( c_bigfft(0:nfft1/2+1) ) + allocate( c_bigfft(0:nfft1/2) ) allocate( c2(0:nfft2-1) ) allocate( cframe(0:160*nss-1) ) @@ -232,10 +232,9 @@ contains ! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. - do i=1,nfft1/2 - c_bigfft(i)=cmplx(float(iwave(2*i-1)),float(iwave(2*i))) + do i=0,nfft1/2 + c_bigfft(i)=cmplx(float(iwave(2*i+1)),float(iwave(2*i+2))) enddo - c_bigfft(nfft1/2+1)=0. call four2a(c_bigfft,nfft1,1,-1,0) if(iwspr.eq.0) then itype1=1 @@ -727,7 +726,7 @@ contains subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & minsync,ncand,candidates,base) - complex c_bigfft(0:nfft1/2+1) !Full length FFT of raw data + complex c_bigfft(0:nfft1/2) !Full length FFT of raw data integer hmod !Modulation index (submode) integer im(1) !For maxloc real candidates(100,4) !Candidate list From 7118f1ad148d605d976a16c86f08e3f8c3079f75 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 12 Jul 2020 01:38:36 +0100 Subject: [PATCH 152/239] Correct T/R period options for older modes, and correct start times Fix up decode window headings. --- widgets/mainwindow.cpp | 93 +++++++++++++++++++++++++----------------- widgets/mainwindow.h | 2 +- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 9c5e9c6bb..65ec87d75 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4211,7 +4211,7 @@ void MainWindow::startTx2() if (m_config.TX_messages ()) { t = " Transmitting " + m_mode + " ----------------------- " + m_config.bands ()->find (m_freqNominal); - t=WSPR_hhmm(0) + ' ' + t.rightJustified (66, '-'); + t=beacon_start_time () + ' ' + t.rightJustified (66, '-'); ui->decodedTextBrowser->appendText(t); } write_all("Tx",m_currentMessage); @@ -5824,11 +5824,8 @@ void MainWindow::on_actionFST240_triggered() // 0123456789012345678901234567890123 displayWidgets(nWidgets("1111110001001111000100000001000000")); setup_status_bar (bVHF); - m_TRperiod = ui->sbTR->value(); - ui->sbTR->setMinimum(15); - ui->sbTR->setMaximum(300); - m_TRperiod = ui->sbTR->value(); - on_sbTR_valueChanged(ui->sbTR->value()); + ui->sbTR->values ({15, 30, 60, 120, 300}); + on_sbTR_valueChanged (ui->sbTR->value()); ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); @@ -5851,16 +5848,9 @@ void MainWindow::on_actionFST240W_triggered() setup_status_bar (bVHF); m_nSubMode=0; ui->sbSubmode->setValue(m_nSubMode); - m_TRperiod = ui->sbTR_FST240W->value (); ui->band_hopping_group_box->setChecked(false); ui->band_hopping_group_box->setVisible(false); - int ntr=m_TRperiod; - ui->sbTR_FST240W->setMinimum(15); - ui->sbTR_FST240W->setMaximum(300); - ui->sbTR_FST240W->setValue(120); //### Why is all this necessary? ### - ui->sbTR_FST240W->setValue(300); - ui->sbTR_FST240W->setValue(ntr); - m_TRperiod = ui->sbTR_FST240W->value(); + on_sbTR_FST240W_valueChanged (ui->sbTR_FST240W->value ()); ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); @@ -6089,18 +6079,22 @@ void MainWindow::on_actionJT9_triggered() } ui->sbSubmode->setMaximum(7); if(m_bFast9) { - m_TRperiod = ui->sbTR->value (); + ui->sbTR->values ({5, 10, 15, 30}); + on_sbTR_valueChanged (ui->sbTR->value()); m_wideGraph->hide(); m_fastGraph->showNormal(); ui->TxFreqSpinBox->setValue(700); ui->RxFreqSpinBox->setValue(700); - ui->decodedTextLabel->setText("UTC dB T Freq " + tr ("Message")); - ui->decodedTextLabel2->setText("UTC dB T Freq " + tr ("Message")); + ui->decodedTextLabel->setText(" UTC dB T Freq " + tr ("Message")); + ui->decodedTextLabel2->setText(" UTC dB T Freq " + tr ("Message")); } else { ui->cbAutoSeq->setChecked(false); - m_TRperiod=60.0; - ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); - ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message")); + if (m_mode != "FST240") + { + m_TRperiod=60.0; + ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); + ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message")); + } } m_wideGraph->setPeriod(m_TRperiod,m_nsps); m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe @@ -6240,7 +6234,8 @@ void MainWindow::on_actionISCAT_triggered() m_mode="ISCAT"; m_modeTx="ISCAT"; ui->actionISCAT->setChecked(true); - m_TRperiod = ui->sbTR->value (); + ui->sbTR->values ({5, 10, 15, 30}); + on_sbTR_valueChanged (ui->sbTR->value ()); m_modulator->setTRPeriod(m_TRperiod); m_detector->setTRPeriod(m_TRperiod); m_wideGraph->setPeriod(m_TRperiod,m_nsps); @@ -6307,7 +6302,8 @@ void MainWindow::on_actionMSK144_triggered() VHF_features_enabled(true); m_bFastMode=true; m_bFast9=false; - m_TRperiod = ui->sbTR->value (); + ui->sbTR->values ({5, 10, 15, 30}); + on_sbTR_valueChanged (ui->sbTR->value()); m_wideGraph->hide(); m_fastGraph->showNormal(); ui->TxFreqSpinBox->setValue(1500); @@ -6315,8 +6311,8 @@ void MainWindow::on_actionMSK144_triggered() ui->RxFreqSpinBox->setMinimum(1400); ui->RxFreqSpinBox->setMaximum(1600); ui->RxFreqSpinBox->setSingleStep(10); - ui->decodedTextLabel->setText("UTC dB T Freq " + tr ("Message")); - ui->decodedTextLabel2->setText("UTC dB T Freq " + tr ("Message")); + ui->decodedTextLabel->setText(" UTC dB T Freq " + tr ("Message")); + ui->decodedTextLabel2->setText(" UTC dB T Freq " + tr ("Message")); m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_fastGraph->setTRPeriod(m_TRperiod); @@ -6411,7 +6407,8 @@ void MainWindow::on_actionFreqCal_triggered() ui->actionFreqCal->setChecked(true); switch_mode(Modes::FreqCal); m_wideGraph->setMode(m_mode); - m_TRperiod = ui->sbTR->value (); + ui->sbTR->values ({5, 10, 15, 30}); + on_sbTR_valueChanged (ui->sbTR->value()); m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; //For symspec only @@ -6486,10 +6483,10 @@ void MainWindow::WSPR_config(bool b) Q_EMIT m_config.transceiver_tx_frequency (0); // turn off split } m_bSimplex = true; - } else { - ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); - m_bSimplex = false; - } + } else + { + m_bSimplex = false; + } enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook } @@ -7420,6 +7417,25 @@ void MainWindow::on_sbTR_valueChanged(int value) // if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode; if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST240" or m_mode=="FST240W") { m_TRperiod = value; + if (m_mode == "FST240" || m_mode == "FST240W") + { + if (m_TRperiod < 60) + { + ui->decodedTextLabel->setText(" UTC dB DT Freq " + tr ("Message")); + if (m_mode != "FST240W") + { + ui->decodedTextLabel2->setText(" UTC dB DT Freq " + tr ("Message")); + } + } + else + { + ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); + if (m_mode != "FST240W") + { + ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message")); + } + } + } m_fastGraph->setTRPeriod (value); m_modulator->setTRPeriod (value); // TODO - not thread safe m_detector->setTRPeriod (value); // TODO - not thread safe @@ -7716,7 +7732,7 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout if(m_nWSPRdecodes==0 and ui->band_hopping_group_box->isChecked()) { t = " " + tr ("Receiving") + " " + m_mode + " ----------------------- " + m_config.bands ()->find (m_dialFreqRxWSPR); - t=WSPR_hhmm(-60) + ' ' + t.rightJustified (66, '-'); + t=beacon_start_time (-m_TRperiod / 2) + ' ' + t.rightJustified (66, '-'); ui->decodedTextBrowser->appendText(t); } killFileTimer.start (45*1000); //Kill in 45s (for slow modes) @@ -7803,20 +7819,23 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout } } -QString MainWindow::WSPR_hhmm(int n) +QString MainWindow::beacon_start_time (int n) { - QDateTime t=QDateTime::currentDateTimeUtc().addSecs(n); - int m=t.toString("hhmm").toInt()/2; - QString t1; - t1 = t1.asprintf("%04d",2*m); - return t1; + auto time = QDateTime::currentDateTimeUtc ().addSecs (n).time (); + auto rounded_time = (int ((time.hour () * 10000 + time.minute () * 100 + time.second ()) * 60 / m_TRperiod) * int (m_TRperiod)) / 60; + auto result = QString::number (rounded_time).rightJustified (6, QLatin1Char {'0'}); + if (m_TRperiod < 60) + { + return result; + } + return result.left (4); } void MainWindow::WSPR_history(Frequency dialFreq, int ndecodes) { QDateTime t=QDateTime::currentDateTimeUtc().addSecs(-60); QString t1=t.toString("yyMMdd"); - QString t2=WSPR_hhmm(-60); + QString t2=beacon_start_time (-m_TRperiod / 2); QString t3; t3 = t3.asprintf("%13.6f",0.000001*dialFreq); if(ndecodes<0) { diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 070fbbae5..3653cfd5c 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -728,7 +728,7 @@ private: void freqCalStep(); void setRig (Frequency = 0); // zero frequency means no change void WSPR_history(Frequency dialFreq, int ndecodes); - QString WSPR_hhmm(int n); + QString beacon_start_time (int n = 0); QString WSPR_message(); void fast_config(bool b); void CQTxFreq(); From 479dc1113f015f9c0b3596ba878fdb43f9e45113 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 13 Jul 2020 13:27:12 +0100 Subject: [PATCH 153/239] Use non-averaging decodes window headings for FST240 --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 65ec87d75..a7748d824 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5813,6 +5813,8 @@ void MainWindow::on_actionFST240_triggered() { int nsub=m_nSubMode; on_actionJT65_triggered(); + ui->label_6->setText(tr ("Band Activity")); + ui->label_7->setText(tr ("Rx Frequency")); ui->sbSubmode->setMaximum(3); m_nSubMode=nsub; ui->sbSubmode->setValue(m_nSubMode); From bac3cc747153ec5758a40851cb53c58d216b6c6f Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 13 Jul 2020 08:53:11 -0500 Subject: [PATCH 154/239] Remove spurious invocation of thresh variable. --- lib/fst240_decode.f90 | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index b57cc401d..93a454b63 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -788,17 +788,15 @@ contains iploc=ia+im(1)-1 !Index of CCF peak pval=s2(iploc) !Peak value if(pval.lt.minsync) exit - if(s2(iploc).gt.thresh) then !Is this a possible candidate? - do i=-3,+3 !Remove 0.9 of a model CCF at - k=iploc+2*hmod*i !this frequency from s2() - if(k.ge.ia .and. k.le.ib) then - s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) - endif - enddo - ncand=ncand+1 - candidates(ncand,1)=df2*iploc !Candidate frequency - candidates(ncand,2)=pval !Rough estimate of SNR - endif + do i=-3,+3 !Remove 0.9 of a model CCF at + k=iploc+2*hmod*i !this frequency from s2() + if(k.ge.ia .and. k.le.ib) then + s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) + endif + enddo + ncand=ncand+1 + candidates(ncand,1)=df2*iploc !Candidate frequency + candidates(ncand,2)=pval !Rough estimate of SNR enddo return From db3e0d80226e8ac221e201a6bb8ec4d54e01dc70 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 13 Jul 2020 14:58:50 -0500 Subject: [PATCH 155/239] Add a disabled option to print the reference waveform to fort.51. --- lib/fst240/gen_fst240wave.f90 | 6 ------ lib/fst240_decode.f90 | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst240/gen_fst240wave.f90 index 3ba1c2d82..49fc55ab7 100644 --- a/lib/fst240/gen_fst240wave.f90 +++ b/lib/fst240/gen_fst240wave.f90 @@ -87,11 +87,5 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & cwave=cshift(cwave,kshift) endif -! do i=1,nwave -! write(71,3071) i,i/48000.0,wave(i) -!3071 format(i10,2f15.9) -! enddo - wave(nsps*nsym:)=0. !Kill a stray spike ?? - return end subroutine gen_fst240wave diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 93a454b63..5c3414244 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -547,6 +547,10 @@ contains else call get_fst240_tones_from_bits(message74,itone,1) endif + if(.false.) then + call write_ref(itone,iwave,nsps,nmax,ndown,hmod, & + isbest,fc_synced) + endif xsig=0 do i=1,NN xsig=xsig+s4(itone(i),i)**2 @@ -802,4 +806,21 @@ contains return end subroutine get_candidates_fst240 + subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc) + complex cwave(nmax) + integer itone(160) + integer*2 iwave(nmax) + integer hmod + + wave=0 + fsample=12000.0 + nsym=160 + call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc, & + 1,cwave,wave) + cwave=cshift(cwave,-i0*ndown) + do i=1,nmax + write(51,*) i,iwave(i),real(cwave(i)),imag(cwave(i)) + enddo + end subroutine subtract240 + end module fst240_decode From a19d5d15568c3f7db93ceb6d31fece61c36794ed Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 13 Jul 2020 15:10:01 -0500 Subject: [PATCH 156/239] Fix end subroutine line for new write_ref subroutine. --- lib/fst240_decode.f90 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 5c3414244..0b8dd15dd 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -306,7 +306,6 @@ contains call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) call timer('sync240 ',0) - fc1=0.0 if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s is0=1.5*nspsec @@ -391,7 +390,6 @@ contains xdt=(isbest-nspsec)/fs2 if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) - do ijitter=0,jittermax if(ijitter.eq.0) ioffset=0 if(ijitter.eq.1) ioffset=1 @@ -821,6 +819,6 @@ contains do i=1,nmax write(51,*) i,iwave(i),real(cwave(i)),imag(cwave(i)) enddo - end subroutine subtract240 + end subroutine write_ref end module fst240_decode From c5f01870362107b5dbecc665d280ef5b808b94c4 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 13 Jul 2020 19:59:14 -0500 Subject: [PATCH 157/239] Eliminate an unnecessary variable (NN2) in fst240sim.f90. --- lib/fst240/fst240sim.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index b0790a768..fc09a9f73 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -59,8 +59,7 @@ program fst240sim baud=12000.0/nsps !Keying rate (baud) nmax=nsec*12000 nz=nsps*NN - nz2=nsps*NN2 - txt=nz2*dt !Transmission length (s) + txt=nz*dt !Transmission length (s) tt=nsps*dt !Duration of symbols (s) allocate( c0(0:nmax-1) ) allocate( c(0:nmax-1) ) From cbeb81b49955500c1a4160ad1c351fe08c90376f Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 11:27:41 -0400 Subject: [PATCH 158/239] Add LF/MF noise blanker capability for FST240 and FST240W. --- CMakeLists.txt | 1 + lib/blanker.f90 | 52 +++ lib/fst240_decode.f90 | 6 +- lib/symspec.f90 | 12 +- widgets/mainwindow.cpp | 17 +- widgets/mainwindow.ui | 1002 +++++++++++++++++++++------------------- 6 files changed, 599 insertions(+), 491 deletions(-) create mode 100644 lib/blanker.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 15cf9aed0..80199358d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -396,6 +396,7 @@ set (wsjt_FSRCS lib/badmsg.f90 lib/ft8/baseline.f90 lib/ft4/ft4_baseline.f90 + lib/blanker.f90 lib/bpdecode40.f90 lib/bpdecode128_90.f90 lib/ft8/bpdecode174_91.f90 diff --git a/lib/blanker.f90 b/lib/blanker.f90 new file mode 100644 index 000000000..a5c334e3f --- /dev/null +++ b/lib/blanker.f90 @@ -0,0 +1,52 @@ +subroutine blanker(iwave,nz,dwell_time,fblank,npct) + + integer*2 iwave(nz) + integer hist(0:32768) + real dwell_time !Blanking dwell time (s) + real fblank !Fraction of points to be blanked + data ncall/0/,thresh/0.0/,fblanked/0.0/ + save ncall,thresh,fblanked + + ncall=ncall+1 + ndropmax=nint(1.0 + dwell_time*12000.0) + hist=0 + do i=1,nz + n=abs(iwave(i)) + hist(n)=hist(n)+1 + enddo + n=0 + do i=32768,0,-1 + n=n+hist(i) + if(n.ge.nint(nz*fblank/ndropmax)) exit + enddo + thresh=thresh + 0.01*(i-thresh) + if(ncall.eq.1) thresh=i + nthresh=nint(thresh) + ndrop=0 + ndropped=0 + + do i=1,nz + i0=iwave(i) + if(ndrop.gt.0) then + iwave(i)=0 + ndropped=ndropped+1 + ndrop=ndrop-1 + cycle + endif + +! Start to apply blanking + if(abs(iwave(i)).gt.nthresh) then + iwave(i)=0 + ndropped=ndropped+1 + ndrop=ndropmax + endif + enddo + + fblanked=fblanked + 0.1*(float(ndropped)/nz - fblanked) + if(ncall.eq.1) fblanked=float(ndropped)/nz + npct=nint(100.0*fblanked) +! if(mod(ncall,4).eq.0) write(*,3001) thresh,dwell_time,fblank,fblanked,npct +!3001 format(f8.1,f8.4,f6.2,f7.3,i6) + + return +end subroutine blanker diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index b57cc401d..0fffd9f74 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -78,6 +78,8 @@ contains data first/.true./ save first,apbits,nappasses,naptypes,mycall0,hiscall0 +! call blanker(iwave,ntrperiod*12000,0.0,0.2) + this%callback => callback dxcall13=hiscall ! initialize for use in packjt77 @@ -788,7 +790,7 @@ contains iploc=ia+im(1)-1 !Index of CCF peak pval=s2(iploc) !Peak value if(pval.lt.minsync) exit - if(s2(iploc).gt.thresh) then !Is this a possible candidate? + if(s2(iploc).gt.minsync) then !Is this a possible candidate? do i=-3,+3 !Remove 0.9 of a model CCF at k=iploc+2*hmod*i !this frequency from s2() if(k.ge.ia .and. k.le.ib) then @@ -803,5 +805,5 @@ contains return end subroutine get_candidates_fst240 - + end module fst240_decode diff --git a/lib/symspec.f90 b/lib/symspec.f90 index f97757778..5bd0fd902 100644 --- a/lib/symspec.f90 +++ b/lib/symspec.f90 @@ -1,5 +1,5 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & - nminw,pxdb,s,df3,ihsym,npts8,pxdbmax) + nminw,pxdb,s,df3,ihsym,npts8,pxdbmax,bblank,npct) ! Input: ! k pointer to the most recent new data @@ -7,8 +7,6 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & ! nsps samples per symbol, at 12000 Hz ! bLowSidelobes true to use windowed FFTs ! ndiskdat 0/1 to indicate if data from disk -! nb 0/1 status of noise blanker (off/on) -! nbslider NB setting, 0-100 ! Output: ! pxdb raw power (0-90 dB) @@ -31,7 +29,7 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & real*4 tmp(NSMAX) complex cx(0:MAXFFT3/2) integer nch(7) - logical*1 bLowSidelobes + logical*1 bLowSidelobes,bblank common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456) data k0/99999999/,nfft3z/0/ @@ -65,6 +63,12 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & gain=10.0**(0.1*ingain) sq=0. pxmax=0.; + + dwell_time=0.0001 + fblank=0.15 + if(k.gt.k0 .and. bblank) call blanker(shared_data%id2(k0+1:k), & + k-k0,dwell_time,fblank,npct) + do i=k0+1,k x1=shared_data%id2(i) if (abs(x1).gt.pxmax) pxmax = abs(x1); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 9c5e9c6bb..7f6948ea3 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -91,7 +91,7 @@ extern "C" { //----------------------------------------------------- C and Fortran routines void symspec_(struct dec_data *, int* k, double* trperiod, int* nsps, int* ingain, bool* bLowSidelobes, int* minw, float* px, float s[], float* df3, - int* nhsym, int* npts8, float *m_pxmax); + int* nhsym, int* npts8, float *m_pxmax, bool *bblank, int* npct); void hspec_(short int d2[], int* k, int* nutc0, int* ntrperiod, int* nrxfreq, int* ntol, bool* bmsk144, bool* btrain, double const pcoeffs[], int* ingain, @@ -1132,6 +1132,8 @@ void MainWindow::writeSettings() m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ()); m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ()); m_settings->setValue("SplitterState",ui->splitter->saveState()); + m_settings->setValue("Blanker",ui->cbNB->isChecked()); + { QList coeffs; // suitable for QSettings for (auto const& coeff : m_phaseEqCoefficients) @@ -1231,6 +1233,7 @@ void MainWindow::readSettings() ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool()); ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool()); ui->splitter->restoreState(m_settings->value("SplitterState").toByteArray()); + ui->cbNB->setChecked(m_settings->value("Blanker",false).toBool()); { auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients" , QList {0., 0., 0., 0., 0.}).toList (); @@ -1389,8 +1392,13 @@ void MainWindow::dataSink(qint64 frames) if(m_bFastMode) nsps=6912; int nsmo=m_wideGraph->smoothYellow()-1; bool bLowSidelobes=m_config.lowSidelobes(); + bool bblank=ui->cbNB->isChecked() and m_mode.startsWith("FST240"); + int npct=0; symspec_(&dec_data,&k,&m_TRperiod,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, - &m_df3,&m_ihsym,&m_npts8,&m_pxmax); + &m_df3,&m_ihsym,&m_npts8,&m_pxmax,&bblank,&npct); + QString t=" "; + if(bblank) t=QString::number(npct); + ui->labNpct->setText(t); if(m_mode=="WSPR" or m_mode=="FST240W") wspr_downsample_(dec_data.d2,&k); if(m_ihsym <=0) return; if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer @@ -4079,7 +4087,6 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { -// qDebug() << "onesec" << ui->RoundRobin->currentText(); m_currentBand=m_config.bands()->find(m_freqNominal); if( SpecOp::HOUND == m_config.special_op_id() ) { qint32 tHound=QDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn; @@ -5806,6 +5813,10 @@ void MainWindow::displayWidgets(qint64 n) if(m_mode=="MSK144") b=SpecOp::EU_VHF==m_config.special_op_id(); ui->sbSerialNumber->setVisible(b); m_lastCallsign.clear (); // ensures Tx5 is updated for new modes + b=m_mode.startsWith("FST240"); + ui->labNpct->setVisible(b); + ui->labNB->setVisible(b); + ui->cbNB->setVisible(b); genStdMsgs (m_rpt, true); } diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 91d8e95ba..ef5a882b1 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -554,488 +554,6 @@ - - - - - 0 - 0 - - - - USB dial frequency - - - QLabel { - font-family: MS Shell Dlg 2; - font-size: 16pt; - color : yellow; - background-color : black; -} -QLabel[oob="true"] { - background-color: red; -} - - - - 14.078 000 - - - Qt::AlignCenter - - - 5 - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> - - - Rx Signal - - - 30dB recommended when only noise present -Green when good -Red when clipping may occur -Yellow when too low - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 159 - 175 - 213 - - - - - - - 159 - 175 - 213 - - - - - - - - true - - - DX Call - - - Qt::AlignCenter - - - 5 - - - 2 - - - dxCallEntry - - - - - - - - 0 - 0 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 159 - 175 - 213 - - - - - - - 159 - 175 - 213 - - - - - - - - true - - - DX Grid - - - Qt::AlignCenter - - - 5 - - - 2 - - - dxGridEntry - - - - - - - Callsign of station to be worked - - - - - - Qt::AlignCenter - - - - - - - Search for callsign in database - - - &Lookup - - - - - - - Locator of station to be worked - - - - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - true - - - Az: 251 16553 km - - - Qt::AlignCenter - - - 4 - - - - - - - Add callsign and locator to database - - - Add - - - - - - - - - - Pwr - - - - - - - false - - - <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> - - - If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. - - - QPushButton { - font-family: helvetica; - font-size: 9pt; - font-weight: bold; - background-color: white; - color: black; - border-style: solid; - border-width:1px; - border-radius:10px; - border-color: gray; - max-width:20px; - max-height:20px; - min-width:20px; - min-height:20px; -} -QPushButton[state="error"] { - background-color: red; -} -QPushButton[state="warning"] { - background-color: orange; -} -QPushButton[state="ok"] { - background-color: #00ff00; -} - - - ? - - - - - - - Adjust Tx audio level - - - 450 - - - 0 - - - Qt::Vertical - - - true - - - true - - - QSlider::TicksBelow - - - 50 - - - - - - - <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> - - - Frequency entry - - - Select operating band or enter frequency in MHz or enter kHz increment followed by k. - - - true - - - QComboBox::NoInsert - - - QComboBox::AdjustToMinimumContentsLength - - - - - - - - 0 - 0 - - - - QLabel { - font-family: MS Shell Dlg 2; - font-size: 16pt; - background-color : black; - color : yellow; -} - - - QFrame::StyledPanel - - - QFrame::Sunken - - - 2 - - - 0 - - - <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> - - - Qt::AlignCenter - - - 5 - - - @@ -2808,6 +2326,526 @@ list. The list can be maintained in Settings (F2). + + + + + 0 + 0 + + + + QLabel { + font-family: MS Shell Dlg 2; + font-size: 16pt; + background-color : black; + color : yellow; +} + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 2 + + + 0 + + + <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> + + + Qt::AlignCenter + + + 5 + + + + + + + Pwr + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 159 + 175 + 213 + + + + + + + 159 + 175 + 213 + + + + + + + + true + + + DX Call + + + Qt::AlignCenter + + + 5 + + + 2 + + + dxCallEntry + + + + + + + + 0 + 0 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 159 + 175 + 213 + + + + + + + 159 + 175 + 213 + + + + + + + + true + + + DX Grid + + + Qt::AlignCenter + + + 5 + + + 2 + + + dxGridEntry + + + + + + + Callsign of station to be worked + + + + + + Qt::AlignCenter + + + + + + + Search for callsign in database + + + &Lookup + + + + + + + Locator of station to be worked + + + + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + true + + + Az: 251 16553 km + + + Qt::AlignCenter + + + 4 + + + + + + + Add callsign and locator to database + + + Add + + + + + + + + + + false + + + <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> + + + If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. + + + QPushButton { + font-family: helvetica; + font-size: 9pt; + font-weight: bold; + background-color: white; + color: black; + border-style: solid; + border-width:1px; + border-radius:10px; + border-color: gray; + max-width:20px; + max-height:20px; + min-width:20px; + min-height:20px; +} +QPushButton[state="error"] { + background-color: red; +} +QPushButton[state="warning"] { + background-color: orange; +} +QPushButton[state="ok"] { + background-color: #00ff00; +} + + + ? + + + + + + + Adjust Tx audio level + + + 450 + + + 0 + + + Qt::Vertical + + + true + + + true + + + QSlider::TicksBelow + + + 50 + + + + + + + <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + + Frequency entry + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + + + true + + + QComboBox::NoInsert + + + QComboBox::AdjustToMinimumContentsLength + + + + + + + + 0 + 0 + + + + USB dial frequency + + + QLabel { + font-family: MS Shell Dlg 2; + font-size: 16pt; + color : yellow; + background-color : black; +} +QLabel[oob="true"] { + background-color: red; +} + + + + 14.078 000 + + + Qt::AlignCenter + + + 5 + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + + Rx Signal + + + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + NB + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + From e740019940ec6e0c02f76624c843d9d0d6436355 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 13:18:54 -0400 Subject: [PATCH 159/239] Editorial work by Dave, KC3GPM. --- doc/user_guide/en/controls-functions-status-bar.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/user_guide/en/controls-functions-status-bar.adoc b/doc/user_guide/en/controls-functions-status-bar.adoc index cf6c2a4ab..df82de65e 100644 --- a/doc/user_guide/en/controls-functions-status-bar.adoc +++ b/doc/user_guide/en/controls-functions-status-bar.adoc @@ -1,4 +1,4 @@ -// Status=review +// Status=edited A *Status Bar* at the bottom edge of the main window provides useful information about operating conditions. @@ -9,15 +9,15 @@ image::status-bar-a.png[align="left",alt="Status Bar"] Labels on the *Status Bar* display such information as the program's current operating state, configuration name, operating mode, and the content of your most recent transmitted message. The first label -(operating state) can be Receiving, Tx (for Transmitting), Tune, or -the name of file opened from the *File* menu; this label is +(operating state) can be Receiving, Tx (for Transmitting), Tx: Tune, or +the name of the file opened from the *File* menu. This label is highlighted in green for Receiving, yellow for Tx, red for Tune, and light blue for a file name. When transmitting, the Tx message is displayed exactly as it will be decoded by receiving stations. The second label (as shown above) will be absent if you are using the *Default* setting on the *Configurations* menu. A progress bar shows the elapsed fraction of a Tx or Rx sequence. Finally, if the Watchdog -(WD) timer was enabled on the *Settings | General* tab, a label in the +(WD) timer was enabled on the *Files | Settings | General* tab, a label in the lower right-hand corner displays the number of minutes remaining before timeout. From 4d7f1684ef48d41a4909bcdf1d796a648738c870 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 13:28:50 -0400 Subject: [PATCH 160/239] Editorial work by Dave, KC3GPM. --- doc/user_guide/en/controls-functions-wide-graph.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/user_guide/en/controls-functions-wide-graph.adoc b/doc/user_guide/en/controls-functions-wide-graph.adoc index e269df826..1c11721e9 100644 --- a/doc/user_guide/en/controls-functions-wide-graph.adoc +++ b/doc/user_guide/en/controls-functions-wide-graph.adoc @@ -1,4 +1,4 @@ -// Status=review +// Status=edited The following controls appear at the bottom of the Wide Graph window. Decoding occurs only in the displayed frequency range; otherwise, with @@ -29,7 +29,7 @@ slower, as desired. - A dropdown list below the *Palette* label lets you select from a wide range of waterfall color palettes. -- Click *Adjust* to activate a window that allows you to create a +- Click *Adjust* to activate a window that allows you to import or export a user-defined palette. - Check *Flatten* if you want _WSJT-X_ to compensate for a sloping or @@ -50,10 +50,10 @@ about right, depending on the input signal level, the chosen palette, and your own preferences. Hover the mouse over a control to display a tip reminding you of its function. -- The *Spec nn%* control may be used to set the fractional height of +- The *Spec nn%* control is used to set the fractional height of the spectrum plotted below the waterfall. -- *Smooth* is active only when *Linear Average* has been selected. +- *Smooth* is active only when *Linear Average* is selected. Smoothing the displayed spectrum over more than one bin can enhance your ability to detect weak EME signals with Doppler spread more than a few Hz. @@ -66,7 +66,7 @@ selected on the Wide Graph. Three sliders at the bottom of the Fast Graph window can be used to optimize gain and zero-offset for the displayed information. Hover the mouse over a control to display a tip reminding you of its function. Clicking the *Auto Level* button -will produce reasonable settings as a starting point. +produces reasonable settings as a starting point. image::fast-graph-controls.png[align="center",alt="Fast Graph Controls"] @@ -89,7 +89,7 @@ spectra, thereby smoothing the curves over multiple bins. - Label *N* shows the number of echo pulses averaged. -- Click the *Colors* button to cycle through 6 possible choices of +- Click the *Colors* button to cycle through six possible choices of color and line width for the plots. [[CONTROLS_MISCELLANEOUS]] From bdc3ebddcc5e2ff770c4c72a0fcc622f93b006d5 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 13:30:31 -0400 Subject: [PATCH 161/239] Editorial work by Dave, KC3GPM. --- doc/user_guide/en/cooperating-programs.adoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/user_guide/en/cooperating-programs.adoc b/doc/user_guide/en/cooperating-programs.adoc index 99e49e1e3..fae3c8429 100644 --- a/doc/user_guide/en/cooperating-programs.adoc +++ b/doc/user_guide/en/cooperating-programs.adoc @@ -1,3 +1,5 @@ +// Status: edited + _WSJT-X_ is programmed to cooperate closely with several other useful programs. @@ -38,10 +40,10 @@ logging applications Aether, MacLoggerDX, RUMlog or RUMlogNG. It checks QSO and QSL status of the call and DXCC entity, as well as many other features. -* {n1mm_logger} is a free full feature contest logging application. It +* {n1mm_logger} is a free, full-feature contest logging application. It is only available for Windows. _WSJT-X_ can send logged QSO information to it via a network connection. -* {writelog} is a non-free full feature contest logging +* {writelog} is a non-free, full-feature contest logging application. It is only available for Windows. _WSJT-X_ can send logged QSO information to it via a network connection. \ No newline at end of file From 4213e029054f79785792360fd69570dd59d68bea Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 13:45:32 -0400 Subject: [PATCH 162/239] Editorial work by Dave, KC3GPM. --- doc/user_guide/en/decoder_notes.adoc | 45 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/doc/user_guide/en/decoder_notes.adoc b/doc/user_guide/en/decoder_notes.adoc index 4227b408c..afa46e820 100644 --- a/doc/user_guide/en/decoder_notes.adoc +++ b/doc/user_guide/en/decoder_notes.adoc @@ -1,19 +1,21 @@ -[[AP_Decoding]] +// Status: edited + === AP Decoding -The _WSJT-X_ decoders for FT4, FT8, JT65, and QRA64 include optional -procedures that take advantage of naturally accumulating information -during a minimal QSO. This _a priori_ (AP) information increases -sensitivity of the decoder by up to 4 dB, at the cost of a slightly -higher rate of false decodes. +The _WSJT-X_ decoders for FT4, FT8, JT65, QRA64, include +procedures that use naturally accumulating information during a +minimal QSO. This _a priori_ (AP) information increases sensitivity +of the decoder by up to 4 dB, at the cost of a slightly higher rate of +false decodes. AP is optional in FT8, JT65, and QRA64, but is always +enabled for FT4. For example: when you decide to answer a CQ, you already know your own callsign and that of your potential QSO partner. The software therefore "`knows`" what might be expected for at least 57 message -bits (28 for each of two callsigns, 1 or more for message type) in the -next received message. The decoder's task can thus be reduced to +bits (28 for each of two callsigns, one or more for message type) in the +next received message. The decoder's task is thus reduced to determining the remaining 15 bits of the message and ensuring that the -resulting solution is consistent with the message's parity symbols. +resulting solution is reliable. AP decoding starts by setting AP bits to the hypothesized values, as if they had been received correctly. We then determine whether the @@ -21,12 +23,12 @@ remaining message and parity bits are consistent with the hypothesized AP bits, with a specified level of confidence. Successful AP decodes are labeled with an end-of-line indicator of the form `aP`, where `P` is one of the single-digit AP decoding types listed in Table 1. For -example, `a2` indicates that the successful decode used *MyCall* as +example, `a2` indicates that the successful decode used MyCall as hypothetically known information. [[FT8_AP_INFO_TABLE]] .FT4 and FT8 AP information types -[width="50%",cols="h10, Date: Tue, 14 Jul 2020 13:47:52 -0400 Subject: [PATCH 163/239] Editorial work by Dave, KC3GPM. --- doc/user_guide/en/faq.adoc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/user_guide/en/faq.adoc b/doc/user_guide/en/faq.adoc index 2152c3c74..c4f20a04a 100644 --- a/doc/user_guide/en/faq.adoc +++ b/doc/user_guide/en/faq.adoc @@ -1,10 +1,12 @@ +// Status: edited + //// Questions: - Should be short one liners (in the .adoc file) ending with ?:: - If your question is too long for one line, consider multiple questions or rephrase + Should be short one-liners (in the .adoc file) ending with ?:: + If your question is too long for one line, consider multiple questions or rephrase. Answers: - Can be bullet or paragraphs. Bullets make for easier reading. + Can be bullets or paragraphs. Bullets make for easier reading. Bullet Usage: * = a circle bullet single intent @@ -53,19 +55,18 @@ You need to install suitable _OpenSSL_ libraries - see <Configuratio The KDE development team have added code to Qt that tries to automatically add shortcut accelerator keys to all buttons including -pop up menu buttons, this interferes with operation of the application +pop up menu buttons. This interferes with operation of the application (many other Qt applications have similar issues with KDE). Until this -is fixed by the KDE team you must disable this misfeature. Edit the -file ~/.config/kdeglobals and add a section containing the following: +is fixed by the KDE team you must disable this feature. Edit the +file `~/.config/kdeglobals` and add a section containing the following: [Development] AutoCheckAccelerators=false From 85986447509e24eb0e0a58458b8284c50ddf0507 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 14:09:23 -0400 Subject: [PATCH 164/239] No need for E or H end-of-line info. --- doc/user_guide/en/decoder_notes.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/user_guide/en/decoder_notes.adoc b/doc/user_guide/en/decoder_notes.adoc index afa46e820..fafbdcd4e 100644 --- a/doc/user_guide/en/decoder_notes.adoc +++ b/doc/user_guide/en/decoder_notes.adoc @@ -128,9 +128,7 @@ End of line information:: `a` - Decoded with aid of some _a priori_ (AP) information + `C` - Confidence indicator [ISCAT and Deep Search; (0-9,*)] + `d` - Deep Search algorithm + - `E` - Size of MSK eye diagram opening - if negative, the eye is closed + `f` - Franke-Taylor or Fano algorithm + - `H` - Number of bit errors corrected + `M` - Message length (characters) + `N` - Number of Rx intervals or frames averaged + `P` - Number indicating type of AP information (Table 1, above) + From 8ff7da38845db2421bcd8b12d0a6739a870a204d Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 14:51:40 -0400 Subject: [PATCH 165/239] FST240W should Tx at audio freq in WSPRfreqSpinBox, not TxFreqSpinBox. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 47a51ebb5..69044e2cc 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -7182,7 +7182,7 @@ void MainWindow::transmit (double snr) if(m_TRperiod==300) nsps=21504; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; - double f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; + double f0=ui->WSPRFreqSpinBox->value() - m_XIT + 1.5*dfreq; Q_EMIT sendMessage (m_mode, NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); From 79dbdcca9c9a59e316a843e2d456b94e8f916813 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 14:54:40 -0400 Subject: [PATCH 166/239] Correct a typo. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 69044e2cc..898de1c6f 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -7182,7 +7182,7 @@ void MainWindow::transmit (double snr) if(m_TRperiod==300) nsps=21504; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; - double f0=ui->WSPRFreqSpinBox->value() - m_XIT + 1.5*dfreq; + double f0=ui->WSPRfreqSpinBox->value() - m_XIT + 1.5*dfreq; Q_EMIT sendMessage (m_mode, NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); From ab3630b2e7d156fa1e92d26de3ecd254cc13722c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 14 Jul 2020 16:46:28 -0400 Subject: [PATCH 167/239] Compute spectrum for measuring fspread of a decoded FST240/FST240W signal. --- lib/fst240_decode.f90 | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 2af2b94c5..f566553eb 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -64,7 +64,7 @@ contains integer mcq(29),mrrr(19),m73(19),mrr73(19) logical badsync,unpk77_success,single_decode - logical first,nohiscall,lwspr + logical first,nohiscall,lwspr,ex integer*2 iwave(300*12000) @@ -547,7 +547,8 @@ contains else call get_fst240_tones_from_bits(message74,itone,1) endif - if(.false.) then + inquire(file='plotspec',exist=ex) + if(ex) then call write_ref(itone,iwave,nsps,nmax,ndown,hmod, & isbest,fc_synced) endif @@ -808,6 +809,7 @@ contains subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc) complex cwave(nmax) + complex c(0:1440000-1) integer itone(160) integer*2 iwave(nmax) integer hmod @@ -817,10 +819,28 @@ contains nsym=160 call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc, & 1,cwave,wave) - cwave=cshift(cwave,-i0*ndown) - do i=1,nmax - write(51,*) i,iwave(i),real(cwave(i)),imag(cwave(i)) + cwave=cshift(cwave,-i0*ndown) +! do i=1,nmax +! write(51,1000) i,iwave(i),cwave(i) +!1000 format(2i10,f12.6) +! enddo + + fac=1.0/32768 + c=fac*float(iwave)*conjg(cwave) + call four2a(c,nmax,1,-1,1) !Forward c2c FFT + df=12000.0/nmax + ia=-10.0/df + ib=10.0/df + do i=ia,ib + j=i + if(j.lt.0) j=i+nmax + s=real(c(j))**2 + aimag(c(j))**2 + f=i*df + write(52,1010) f,s,db(s) +1010 format(f10.3,e12.3,f10.3) enddo + + return end subroutine write_ref end module fst240_decode From 99f419f63cecfc14f38d8e93d31885b222bd5700 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 15 Jul 2020 01:46:52 +0100 Subject: [PATCH 168/239] Initialize prefix store for type 2 50-bit messages --- lib/77bit/packjt77.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index dc6fb0f17..5fc335393 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -374,6 +374,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) call unpack28(n28,call_1,unpk28_success) if(.not.unpk28_success) unpk77_success=.false. write(crpt,'(i3)') idbm + cpfx=' ' if(npfx.lt.nzzz) then ! Prefix do i=3,1,-1 @@ -388,7 +389,6 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) else ! Suffix npfx=npfx-nzzz - cpfx=' ' if(npfx.le.35) then cpfx(1:1)=a2(npfx+1:npfx+1) else if(npfx.gt.35 .and. npfx.le.1295) then From 785e9e7924ebae1ea5e68f4613e90ea1930ad35e Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 15 Jul 2020 14:45:08 +0100 Subject: [PATCH 169/239] Undo a change only intended to testing --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 898de1c6f..bd130db0b 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3455,7 +3455,7 @@ void MainWindow::auto_sequence (DecodedText const& message, unsigned start_toler void MainWindow::pskPost (DecodedText const& decodedtext) { -//### if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return; + if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return; QString msgmode=m_mode; if(m_mode=="JT9+JT65") { From fe86a6562cd84ea4933a636d7022a6d66d85c77a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 15 Jul 2020 13:09:34 -0400 Subject: [PATCH 170/239] Change band name 2190m to 2200m. --- models/Bands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/Bands.cpp b/models/Bands.cpp index 832c36185..aa21eae9e 100644 --- a/models/Bands.cpp +++ b/models/Bands.cpp @@ -15,7 +15,7 @@ namespace Radio::Frequency lower_bound_; Radio::Frequency upper_bound_; } constexpr ADIF_bands[] = { - {"2190m", 136000u, 137000u}, + {"2200m", 136000u, 137000u}, {"630m", 472000u, 479000u}, {"560m", 501000u, 504000u}, {"160m", 1800000u, 2000000u}, From ff0d31986f7b8fd52df59143331c016bae3f416c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 15 Jul 2020 13:15:38 -0400 Subject: [PATCH 171/239] File 'plotspec' in execution directory ==> save channel-gain spectrum to fort.52. --- lib/fst240_decode.f90 | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f566553eb..9d37f5eb7 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -809,11 +809,15 @@ contains subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc) complex cwave(nmax) - complex c(0:1440000-1) + complex, allocatable :: c(:) integer itone(160) integer*2 iwave(nmax) integer hmod + data ncall/0/ + save ncall + ncall=ncall+1 + allocate( c(0:nmax-1) ) wave=0 fsample=12000.0 nsym=160 @@ -829,17 +833,26 @@ contains c=fac*float(iwave)*conjg(cwave) call four2a(c,nmax,1,-1,1) !Forward c2c FFT df=12000.0/nmax - ia=-10.0/df - ib=10.0/df + ia=-10.1/df + ib=10.1/df + smax=0. do i=ia,ib j=i if(j.lt.0) j=i+nmax s=real(c(j))**2 + aimag(c(j))**2 + smax=max(s,smax) + enddo + do i=ia,ib + j=i + if(j.lt.0) j=i+nmax + s=(real(c(j))**2 + aimag(c(j))**2)/smax + s=s + ncall-1 f=i*df write(52,1010) f,s,db(s) -1010 format(f10.3,e12.3,f10.3) +1010 format(f12.6,f12.6,f10.3) enddo - +! close(52) + return end subroutine write_ref From b3882a93c0760c4e3ae28d775a6590ac58bdb8ee Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 15 Jul 2020 15:50:17 -0400 Subject: [PATCH 172/239] Extend write_ref() to compute freq offset and Doppler spread. Also some minor code cleanup. --- lib/decoder.f90 | 19 ++++++------ lib/fst240_decode.f90 | 71 +++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 1e9245553..a4359a696 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -196,9 +196,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & - params%ntol,params%nzhsym,params%emedelay, & - logical(params%lapcqonly),params%napwid,mycall,hiscall, & - params%nfsplit,iwspr) + params%ntol,params%emedelay, & + logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) call timer('dec240 ',1) go to 800 endif @@ -211,9 +210,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) call my_fst240%decode(fst240_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & - params%ntol,params%nzhsym,params%emedelay, & - logical(params%lapcqonly),params%napwid,mycall,hiscall, & - params%nfsplit,iwspr) + params%ntol,params%emedelay, & + logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) call timer('dec240 ',1) go to 800 endif @@ -700,7 +698,7 @@ contains end subroutine ft4_decoded subroutine fst240_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & - qual,ntrperiod,lwspr) + qual,ntrperiod,lwspr,fmid,w50) use fst240_decode implicit none @@ -716,6 +714,8 @@ contains real, intent(in) :: qual integer, intent(in) :: ntrperiod logical, intent(in) :: lwspr + real, intent(in) :: fmid + real, intent(in) :: w50 character*2 annot character*37 decoded0 @@ -733,8 +733,9 @@ contains write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') else - write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot -1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2) + if(fmid.ne.-999.0) write(decoded0(16:21),'(f6.3)') w50 + write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot +1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2,2f7.3) write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') endif diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 9d37f5eb7..697b3df5b 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -8,7 +8,7 @@ module fst240_decode abstract interface subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & - decoded,nap,qual,ntrperiod,lwspr) + decoded,nap,qual,ntrperiod,lwspr,fmid,w50) import fst240_decoder implicit none class(fst240_decoder), intent(inout) :: this @@ -22,14 +22,16 @@ module fst240_decode real, intent(in) :: qual integer, intent(in) :: ntrperiod logical, intent(in) :: lwspr + real, intent(in) :: fmid + real, intent(in) :: w50 end subroutine fst240_decode_callback end interface contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & - nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol,nzhsym, & - emedelay,lapcqonly,napwid,mycall,hiscall,nfsplit,iwspr) + nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol, & + emedelay,lapcqonly,mycall,hiscall,nfsplit,iwspr) use timer_module, only: timer use packjt77 @@ -548,9 +550,10 @@ contains call get_fst240_tones_from_bits(message74,itone,1) endif inquire(file='plotspec',exist=ex) + fmid=-999.0 if(ex) then call write_ref(itone,iwave,nsps,nmax,ndown,hmod, & - isbest,fc_synced) + isbest,fc_synced,fmid,w50) endif xsig=0 do i=1,NN @@ -572,7 +575,7 @@ contains ! nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg ! flush(21) call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual,ntrperiod,lwspr) + iaptype,qual,ntrperiod,lwspr,fmid,w50) goto 2002 endif enddo ! metrics @@ -807,9 +810,10 @@ contains return end subroutine get_candidates_fst240 - subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc) + subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50) complex cwave(nmax) complex, allocatable :: c(:) + real,allocatable :: ss(:) integer itone(160) integer*2 iwave(nmax) integer hmod @@ -817,10 +821,11 @@ contains save ncall ncall=ncall+1 - allocate( c(0:nmax-1) ) + allocate(c(0:nmax-1)) wave=0 fsample=12000.0 nsym=160 + call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc, & 1,cwave,wave) cwave=cshift(cwave,-i0*ndown) @@ -832,26 +837,60 @@ contains fac=1.0/32768 c=fac*float(iwave)*conjg(cwave) call four2a(c,nmax,1,-1,1) !Forward c2c FFT + df=12000.0/nmax - ia=-10.1/df - ib=10.1/df + ia=1.0/df smax=0. - do i=ia,ib + do i=-ia,ia j=i if(j.lt.0) j=i+nmax s=real(c(j))**2 + aimag(c(j))**2 smax=max(s,smax) enddo - do i=ia,ib + ia=10.1/df + allocate(ss(-ia:ia)) + sum1=0. + sum2=0. + ns=0 + do i=-ia,ia j=i if(j.lt.0) j=i+nmax - s=(real(c(j))**2 + aimag(c(j))**2)/smax - s=s + ncall-1 + ss(i)=(real(c(j))**2 + aimag(c(j))**2)/smax f=i*df - write(52,1010) f,s,db(s) -1010 format(f12.6,f12.6,f10.3) + if(f.ge.-4.0 .and. f.le.-2.0) then + sum1=sum1 + ss(i) + ns=ns+1 + else if(f.ge.2.0 .and. f.le.4.0) then + sum2=sum2 + ss(i) + endif enddo -! close(52) + avg=min(sum1/ns,sum2/ns) + + sum1=0. + do i=-ia,ia + f=i*df + if(abs(f).le.1.0) sum1=sum1 + ss(i)-avg + y=0.99*ss(i) + ncall-1 + write(52,1010) f,y +1010 format(f12.6,f12.6) + enddo + + ia=nint(1.0/df) + sum2=0.0 + i1=-999 + i2=-999 + i3=-999 + do i=-ia,ia + sum2=sum2 + ss(i)-avg + if(sum2.ge.0.25*sum1 .and. i1.eq.-999) i1=i + if(sum2.ge.0.50*sum1 .and. i2.eq.-999) i2=i + if(sum2.ge.0.75*sum1) then + i3=i + exit + endif + enddo + fmid=i2*df + w50=(i3-i1+1)*df return end subroutine write_ref From f61cb1dcbd181dd1e6bf441811933542958ede6a Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 15 Jul 2020 16:03:36 -0400 Subject: [PATCH 173/239] Better display format for w50 with plotspec. --- lib/decoder.f90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index a4359a696..27c49a82c 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -733,7 +733,11 @@ contains write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') else - if(fmid.ne.-999.0) write(decoded0(16:21),'(f6.3)') w50 + if(fmid.ne.-999.0) then + if(w50.lt.0.95) write(decoded0(18:22),'(f5.3)') w50 + if(w50.ge.0.95) write(decoded0(18:22),'(f5.2)') w50 + if(decoded0(18:18).eq.'0') decoded0(18:18)=' ' + endif write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot 1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2,2f7.3) write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 From 74970acdb72e9151966e7c0ef546b2125e64fed1 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 16 Jul 2020 14:09:24 +0100 Subject: [PATCH 174/239] Align FST240W round-robin scheduling with hours --- widgets/mainwindow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index bd130db0b..3f08eefda 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3591,11 +3591,11 @@ void MainWindow::guiUpdate() if(m_mode=="WSPR" or m_mode=="FST240W") { if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx m_tuneup=false; //This is not an ATU tuneup - if(m_pctx==0) m_WSPR_tx_next = false; //Don't transmit if m_pctx=0 + if(ui->sbTxPercent->isEnabled () && m_pctx==0) m_WSPR_tx_next = false; //Don't transmit if m_pctx=0 bool btx = m_auto && m_WSPR_tx_next; // To Tx, we need m_auto and // scheduled transmit if(m_auto and m_txNext) btx=true; //TxNext button overrides - if(m_auto and m_pctx==100) btx=true; //Always transmit + if(m_auto && ui->sbTxPercent->isEnabled () && m_pctx==100) btx=true; //Always transmit if(btx) { m_ntr=-1; //This says we will have transmitted @@ -7946,13 +7946,13 @@ void MainWindow::WSPR_scheduling () { QString t=ui->RoundRobin->currentText(); if(m_mode=="FST240W" and t!="Random") { - int i=t.left(1).toInt(); + int i=t.left (1).toInt () - 1; int n=t.right(1).toInt(); qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000; int nsec=ms/1000; int ntr=m_TRperiod; - int j=(nsec % (n*ntr))/ntr + 1; + int j=((nsec+ntr) % (n*ntr))/ntr; m_WSPR_tx_next=(i==j); return; } From 7bd797c0e9a9b1d88bf0eb56843637de8d972dd8 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 16 Jul 2020 11:47:07 -0400 Subject: [PATCH 175/239] Improved estimates of Doppler spread. Comment the code in write_ref(). --- lib/fst240_decode.f90 | 165 ++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 77 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 697b3df5b..ca2975145 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -811,88 +811,99 @@ contains end subroutine get_candidates_fst240 subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50) - complex cwave(nmax) - complex, allocatable :: c(:) - real,allocatable :: ss(:) - integer itone(160) - integer*2 iwave(nmax) - integer hmod - data ncall/0/ - save ncall - ncall=ncall+1 - allocate(c(0:nmax-1)) - wave=0 - fsample=12000.0 - nsym=160 +! On "plotspec" special request, compute Doppler spread for a decoded signal - call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc, & - 1,cwave,wave) - cwave=cshift(cwave,-i0*ndown) -! do i=1,nmax -! write(51,1000) i,iwave(i),cwave(i) -!1000 format(2i10,f12.6) -! enddo + complex, allocatable :: cwave(:) !Reconstructed complex signal + complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper + real,allocatable :: ss(:) !Computed power spectrum of g(t) + integer itone(160) !Tones for this message + integer*2 iwave(nmax) !Raw Rx data + integer hmod !Modulation index + data ncall/0/ + save ncall - fac=1.0/32768 - c=fac*float(iwave)*conjg(cwave) - call four2a(c,nmax,1,-1,1) !Forward c2c FFT + ncall=ncall+1 + nfft=2*nmax + allocate(cwave(0:nmax-1)) + allocate(g(0:nfft-1)) + wave=0 + fsample=12000.0 + nsym=160 + call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc,1,cwave,wave) + cwave=cshift(cwave,-i0*ndown) + fac=1.0/32768 + g(0:nmax-1)=fac*float(iwave)*conjg(cwave) + g(nmax:)=0. + call four2a(g,nfft,1,-1,1) !Forward c2c FFT - df=12000.0/nmax - ia=1.0/df - smax=0. - do i=-ia,ia - j=i - if(j.lt.0) j=i+nmax - s=real(c(j))**2 + aimag(c(j))**2 - smax=max(s,smax) - enddo - ia=10.1/df - allocate(ss(-ia:ia)) - sum1=0. - sum2=0. - ns=0 - do i=-ia,ia - j=i - if(j.lt.0) j=i+nmax - ss(i)=(real(c(j))**2 + aimag(c(j))**2)/smax - f=i*df - if(f.ge.-4.0 .and. f.le.-2.0) then - sum1=sum1 + ss(i) - ns=ns+1 - else if(f.ge.2.0 .and. f.le.4.0) then - sum2=sum2 + ss(i) - endif - enddo - avg=min(sum1/ns,sum2/ns) + df=12000.0/nfft + ia=1.0/df + smax=0. + do i=-ia,ia !Find smax in +/- 1 Hz around 0. + j=i + if(j.lt.0) j=i+nfft + s=real(g(j))**2 + aimag(g(j))**2 + smax=max(s,smax) + enddo + + ia=10.1/df + allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz + sum1=0. + sum2=0. + ns=0 + do i=-ia,ia + j=i + if(j.lt.0) j=i+nfft + ss(i)=(real(g(j))**2 + aimag(g(j))**2)/smax + f=i*df + if(f.ge.-4.0 .and. f.le.-2.0) then + sum1=sum1 + ss(i) !Power between -2 and -4 Hz + ns=ns+1 + else if(f.ge.2.0 .and. f.le.4.0) then + sum2=sum2 + ss(i) !Power between +2 and +4 Hz + endif + enddo + avg=min(sum1/ns,sum2/ns) !Compute avg from smaller sum - sum1=0. - do i=-ia,ia - f=i*df - if(abs(f).le.1.0) sum1=sum1 + ss(i)-avg - y=0.99*ss(i) + ncall-1 - write(52,1010) f,y -1010 format(f12.6,f12.6) - enddo + sum1=0. + do i=-ia,ia + f=i*df + if(abs(f).le.1.0) sum1=sum1 + ss(i)-avg !Power in abs(f) < 1 Hz + enddo - ia=nint(1.0/df) - sum2=0.0 - i1=-999 - i2=-999 - i3=-999 - do i=-ia,ia - sum2=sum2 + ss(i)-avg - if(sum2.ge.0.25*sum1 .and. i1.eq.-999) i1=i - if(sum2.ge.0.50*sum1 .and. i2.eq.-999) i2=i - if(sum2.ge.0.75*sum1) then - i3=i - exit - endif - enddo - fmid=i2*df - w50=(i3-i1+1)*df - - return - end subroutine write_ref + ia=nint(1.0/df) + 1 + sum2=0.0 + xi1=-999 + xi2=-999 + xi3=-999 + sum2z=0. + do i=-ia,ia !Find freq range that has 50% of signal power + sum2=sum2 + ss(i)-avg + if(sum2.ge.0.25*sum1 .and. xi1.eq.-999.0) then + xi1=i - 1 + (sum2-0.25*sum1)/(sum2-sum2z) + endif + if(sum2.ge.0.50*sum1 .and. xi2.eq.-999.0) then + xi2=i - 1 + (sum2-0.50*sum1)/(sum2-sum2z) + endif + if(sum2.ge.0.75*sum1) then + xi3=i - 1 + (sum2-0.75*sum1)/(sum2-sum2z) + exit + endif + sum2z=sum2 + enddo + xdiff=sqrt(1.0+(xi3-xi1)**2) !Keep small values from fluctuating too widely + w50=xdiff*df !Compute Doppler spread + fmid=xi2*df !Frequency midpoint of signal powere + + do i=-ia,ia !Save the spectrum for plotting + f=i*df + y=0.99*ss(i+nint(xi2)) + ncall-1 + write(52,1010) f,y +1010 format(f12.6,f12.6) + enddo + + return + end subroutine write_ref end module fst240_decode From 02b66241d29bcd31d69209d596bbd41645fb7abb Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 17 Jul 2020 10:52:27 -0500 Subject: [PATCH 176/239] Add 15 minute and 30 minute TRperiod option for FST240. --- lib/fst240/fst240sim.f90 | 2 ++ lib/fst240_decode.f90 | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index fc09a9f73..edf4fb44c 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -52,6 +52,8 @@ program fst240sim if(nsec.eq.60) nsps=3888 if(nsec.eq.120) nsps=8200 if(nsec.eq.300) nsps=21504 + if(nsec.eq.900) nsps=65536 + if(nsec.eq.1800) nsps=131072 if(nsps.eq.0) then print*,'Invalid TR sequence length.' go to 999 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index ca2975145..cce63ab02 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -201,6 +201,16 @@ contains nmax=300*12000 ndown=512/hmod !nss=42,84,168,336 nfft1=int((nmax-200)/ndown)*ndown + else if(ntrperiod.eq.900) then + nsps=65536 + nmax=900*12000 + ndown=1024/hmod !nss=64,128,256,512 + nfft1=int((nmax-200)/ndown)*ndown + else if(ntrperiod.eq.1800) then + nsps=131072 + nmax=1800*12000 + ndown=2048/hmod !nss=64,128,256,512 + nfft1=int((nmax-200)/ndown)*ndown end if nss=nsps/ndown fs=12000.0 !Sample rate From 64dc6c6a6eef531e4213758edfe562da2ac9d703 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 17 Jul 2020 12:00:15 -0400 Subject: [PATCH 177/239] Move the red goal post appropriately when FST240 or FSt240W mode is selected. --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 3f08eefda..2faf2c0f3 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5843,6 +5843,7 @@ void MainWindow::on_actionFST240_triggered() m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setPeriod(m_TRperiod,6912); + m_wideGraph->setTxFreq(ui->TxFreqSpinBox->value()); switch_mode (Modes::FST240); m_wideGraph->setMode(m_mode); statusChanged(); @@ -5868,6 +5869,7 @@ void MainWindow::on_actionFST240W_triggered() m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setPeriod(m_TRperiod,6912); + m_wideGraph->setTxFreq(ui->WSPRfreqSpinBox->value()); ui->sbFtol->setValue(100); ui->RxFreqSpinBox->setValue(1500); switch_mode (Modes::FST240W); From 322fd14a6a11cdd595f3c657e9bceba2d2a933a1 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 17 Jul 2020 11:29:21 -0500 Subject: [PATCH 178/239] Use Joe's values for NSPS. --- lib/fst240/fst240sim.f90 | 4 ++-- lib/fst240_decode.f90 | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index edf4fb44c..cdfc4e561 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -52,8 +52,8 @@ program fst240sim if(nsec.eq.60) nsps=3888 if(nsec.eq.120) nsps=8200 if(nsec.eq.300) nsps=21504 - if(nsec.eq.900) nsps=65536 - if(nsec.eq.1800) nsps=131072 + if(nsec.eq.900) nsps=66560 + if(nsec.eq.1800) nsps=134400 if(nsps.eq.0) then print*,'Invalid TR sequence length.' go to 999 diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index cce63ab02..5976f63ad 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -202,14 +202,14 @@ contains ndown=512/hmod !nss=42,84,168,336 nfft1=int((nmax-200)/ndown)*ndown else if(ntrperiod.eq.900) then - nsps=65536 + nsps=66560 nmax=900*12000 - ndown=1024/hmod !nss=64,128,256,512 + ndown=1664/hmod !nss=40,80,160,320 nfft1=int((nmax-200)/ndown)*ndown else if(ntrperiod.eq.1800) then - nsps=131072 + nsps=134400 nmax=1800*12000 - ndown=2048/hmod !nss=64,128,256,512 + ndown=3360/hmod !nss=40,80,160,320 nfft1=int((nmax-200)/ndown)*ndown end if nss=nsps/ndown From c21a60144a64a3c58340532d2e0cecac79bd2f99 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 17 Jul 2020 19:08:21 +0100 Subject: [PATCH 179/239] Larger 12kHz sample buffer --- commons.h | 2 +- lib/constants.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commons.h b/commons.h index f53bfff99..140c69c6d 100644 --- a/commons.h +++ b/commons.h @@ -2,7 +2,7 @@ #define COMMONS_H #define NSMAX 6827 -#define NTMAX 300 +#define NTMAX 30*60 #define RX_SAMPLE_RATE 12000 #ifdef __cplusplus diff --git a/lib/constants.f90 b/lib/constants.f90 index ea872e8ad..36e81c77b 100644 --- a/lib/constants.f90 +++ b/lib/constants.f90 @@ -1,4 +1,4 @@ - integer, parameter :: NTMAX=300 + integer, parameter :: NTMAX=30*60 integer, parameter :: NMAX=NTMAX*12000 !Total sample intervals (one minute) integer, parameter :: NDMAX=NTMAX*1500 !Sample intervals at 1500 Hz rate integer, parameter :: NSMAX=6827 !Max length of saved spectra From cccb38dbefd2dd1317759442a59ca3e18dd974c0 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 17 Jul 2020 19:09:21 +0100 Subject: [PATCH 180/239] Pass hints to fst240sim, genfst240, and packjt77::pack77 on WSPR msgs Due to an ambiguity with message encodings between 77-bit QSO modes and 50-bit beacon modes with message types 13.n3 4.0 and 0.6 a hint needs to be passed to ensure the right encoding is emitted. The hint only effects ambiguous messages, others will be encoded strictly according to the message content. --- lib/77bit/packjt77.f90 | 73 ++++++++++++++++++++++++++++++---------- lib/fst240/fst240sim.f90 | 24 +++++++++---- lib/fst240/genfst240.f90 | 7 +++- widgets/mainwindow.cpp | 1 + 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 5fc335393..a2499625c 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -124,12 +124,14 @@ subroutine pack77(msg0,i3,n3,c77) integer ntel(3) msg=msg0 - if(i3.eq.0 .and. n3.eq.5) go to 5 + i3_hint=i3 + n3_hint=n3 + i3=-1 + n3=-1 + if(i3_hint.eq.0 .and. n3_hint.eq.5) go to 5 ! Convert msg to upper case; collapse multiple blanks; parse into words. call split77(msg,nwords,nw,w) - i3=-1 - n3=-1 if(msg(1:3).eq.'CQ ' .or. msg(1:3).eq.'DE ' .or. msg(1:4).eq.'QRZ ') go to 100 ! Check 0.1 (DXpedition mode) @@ -160,7 +162,7 @@ subroutine pack77(msg0,i3,n3,c77) go to 900 endif -100 call pack77_06(nwords,w,i3,n3,c77) +100 call pack77_06(nwords,w,i3,n3,c77,i3_hint,n3_hint) if(i3.ge.0) go to 900 ! Check Type 1 (Standard 77-bit message) or Type 2, with optional "/P" @@ -414,7 +416,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) n28=n22+2063592 call unpack28(n28,call_1,unpk28_success) if(.not.unpk28_success) unpk77_success=.false. - call to_grid6(igrid6,grid6) + call to_grid(igrid6,grid6) msg=trim(call_1)//' '//grid6 @@ -938,7 +940,7 @@ subroutine pack77_03(nwords,w,i3,n3,c77) end subroutine pack77_03 -subroutine pack77_06(nwords,w,i3,n3,c77) +subroutine pack77_06(nwords,w,i3,n3,c77,i3_hint,n3_hint) character*13 w(19) character*77 c77 @@ -955,13 +957,14 @@ subroutine pack77_06(nwords,w,i3,n3,c77) grid4(3:3).ge.'0' .and. grid4(3:3).le.'9' .and. & grid4(4:4).ge.'0' .and. grid4(4:4).le.'9' - is_grid6(grid6)=len(trim(grid6)).eq.6 .and. & + is_grid6(grid6)=(len(trim(grid6)).eq.6.or.len(trim(grid6)).eq.4).and. & grid6(1:1).ge.'A' .and. grid6(1:1).le.'R' .and. & grid6(2:2).ge.'A' .and. grid6(2:2).le.'R' .and. & grid6(3:3).ge.'0' .and. grid6(3:3).le.'9' .and. & grid6(4:4).ge.'0' .and. grid6(4:4).le.'9' .and. & - grid6(5:5).ge.'A' .and. grid6(5:5).le.'X' .and. & - grid6(6:6).ge.'A' .and. grid6(6:6).le.'X' + (len(trim(grid6)).eq.4.or. & + (grid6(5:5).ge.'A' .and. grid6(5:5).le.'X' .and. & + grid6(6:6).ge.'A' .and. grid6(6:6).le.'X')) is_digit(c)=c.ge.'0' .and. c.le.'9' @@ -1033,8 +1036,13 @@ subroutine pack77_06(nwords,w,i3,n3,c77) go to 900 endif - if(nwords.eq.2 .and. m1.ge.5 .and. m1.le.12 .and. m2.le.6) then + if(i3_hint.eq.0.and.n3_hint.eq.6.and.nwords.eq.2 .and. m1.ge.5 & + .and. m1.le.12 .and. m2.le.6) then ! WSPR Type 3 + + !n3_hint=6 and i3_hint=0 is a hint that the caller wanted a + !50-bit encoding rather than the possible alternative n3=4 77-bit + !encoding if(index(w(1),'<').lt.1 .or. index(w(1),'>').lt.1) go to 900 grid6=w(2)(1:6) if(.not.is_grid6(grid6)) go to 900 @@ -1042,13 +1050,17 @@ subroutine pack77_06(nwords,w,i3,n3,c77) n3=6 call pack28(w(1),n28) n22=n28-2063592 - k1=(ichar(grid6(1:1))-ichar('A'))*18*10*10*24*24 - k2=(ichar(grid6(2:2))-ichar('A'))*10*10*24*24 - k3=(ichar(grid6(3:3))-ichar('0'))*10*24*24 - k4=(ichar(grid6(4:4))-ichar('0'))*24*24 - k5=(ichar(grid6(5:5))-ichar('A'))*24 - k6=(ichar(grid6(6:6))-ichar('A')) - igrid6=k1+k2+k3+k4+k5+k6 + k1=(ichar(grid6(1:1))-ichar('A'))*18*10*10*25*25 + k2=(ichar(grid6(2:2))-ichar('A'))*10*10*25*25 + k3=(ichar(grid6(3:3))-ichar('0'))*10*25*25 + k4=(ichar(grid6(4:4))-ichar('0'))*25*25 + if (grid6(5:6).eq.' ') then + igrid6=k1+k2+k3+k4+24*25+24 + else + k5=(ichar(grid6(5:5))-ichar('A'))*25 + k6=(ichar(grid6(6:6))-ichar('A')) + igrid6=k1+k2+k3+k4+k5+k6 + endif write(c77,1030) n22,igrid6,2,0,n3,i3 1030 format(b22.22,b25.25,b3.3,b21.21,2b3.3) endif @@ -1523,4 +1535,31 @@ subroutine to_grid6(n,grid6) return end subroutine to_grid6 +subroutine to_grid(n,grid6) + ! 4-, or 6-character grid + character*6 grid6 + + j1=n/(18*10*10*25*25) + n=n-j1*18*10*10*25*25 + j2=n/(10*10*25*25) + n=n-j2*10*10*25*25 + j3=n/(10*25*25) + n=n-j3*10*25*25 + j4=n/(25*25) + n=n-j4*25*25 + j5=n/25 + j6=n-j5*25 + grid6='' + grid6(1:1)=char(j1+ichar('A')) + grid6(2:2)=char(j2+ichar('A')) + grid6(3:3)=char(j3+ichar('0')) + grid6(4:4)=char(j4+ichar('0')) + if (j5.ne.24.or.j6.ne.24) then + grid6(5:5)=char(j5+ichar('A')) + grid6(6:6)=char(j6+ichar('A')) + endif + + return +end subroutine to_grid + end module packjt77 diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index cdfc4e561..338c7c6ba 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -6,6 +6,7 @@ program fst240sim use packjt77 include 'fst240_params.f90' !Set various constants type(hdr) h !Header for .wav file + logical*1 wspr_hint character arg*12,fname*17 character msg37*37,msgsent37*37,c77*77 complex, allocatable :: c0(:) @@ -18,10 +19,11 @@ program fst240sim ! Get command-line argument(s) nargs=iargc() - if(nargs.ne.9) then - print*,'Need 9 arguments, got ',nargs - print*,'Usage: fst240sim "message" TRsec f0 DT h fdop del nfiles snr' - print*,'Examples: fst240sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15' + if(nargs.ne.10) then + print*,'Need 10 arguments, got ',nargs + print*,'Usage: fst240sim "message" TRsec f0 DT h fdop del nfiles snr W' + print*,'Examples: fst240sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15 F' + print*,'W (T or F) argument is hint to encoder to use WSPR message when there is abiguity' go to 999 endif call getarg(1,msg37) !Message to be transmitted @@ -41,6 +43,8 @@ program fst240sim read(arg,*) nfiles !Number of files call getarg(9,arg) read(arg,*) snrdb !SNR_2500 + call getarg(10,arg) + read(arg,*) wspr_hint !0:break ties as 77-bit 1:break ties as 50-bit nfiles=abs(nfiles) twopi=8.0*atan(1.0) @@ -72,12 +76,18 @@ program fst240sim sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) if(snrdb.gt.90.0) sig=1.0 - i3=-1 - n3=-1 + if(wspr_hint) then + i3=0 + n3=6 + else + i3=-1 + n3=-1 + endif call pack77(msg37,i3,n3,c77) + if(i3.eq.0.and.n3.eq.6) iwspr=1 call genfst240(msg37,0,msgsent37,msgbits,itone,iwspr) write(*,*) - write(*,'(a9,a37,a7,i2)') 'Message: ',msgsent37,' iwspr:',iwspr + write(*,'(a9,a37,a3,L2,a7,i2)') 'Message: ',msgsent37,'W:',wspr_hint,' iwspr:',iwspr write(*,1000) f00,xdt,hmod,txt,snrdb 1000 format('f0:',f9.3,' DT:',f6.2,' hmod:',i6,' TxT:',f6.1,' SNR:',f6.1) write(*,*) diff --git a/lib/fst240/genfst240.f90 b/lib/fst240/genfst240.f90 index adb8d20ec..2d4a055ae 100644 --- a/lib/fst240/genfst240.f90 +++ b/lib/fst240/genfst240.f90 @@ -5,7 +5,8 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) ! - ichk if ichk=1, return only msgsent ! - msgsent message as it will be decoded ! - i4tone array of audio tone values, {0,1,2,3} -! - iwspr 0: (240,101)/crc24, 1: (240,74)/crc24 +! - iwspr in: 0: FST240 1: FST240W +! out 0: (240,101)/crc24, 1: (240,74)/crc24 ! ! Frame structure: ! s8 d30 s8 d30 s8 d30 s8 d30 s8 @@ -43,6 +44,10 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) i3=-1 n3=-1 + if(iwspr.eq.1) then + i3=0 + n3=6 + endif call pack77(message,i3,n3,c77) call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent msgbits=0 diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 2faf2c0f3..2487e7a46 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3875,6 +3875,7 @@ void MainWindow::guiUpdate() char fst240msgbits[101]; QString wmsg; if(m_mode=="FST240W") { + iwspr = 1; wmsg=WSPR_message(); ba=wmsg.toLatin1(); ba2msg(ba,message); From 4e0f1103b60a06ecfb306d30a715b69e0e43d460 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 17 Jul 2020 23:44:14 +0100 Subject: [PATCH 181/239] 15 and 30 minute T/R periods for FST240 & FST240W --- lib/fst240/fst240sim.f90 | 13 +++++++------ lib/fst240_decode.f90 | 28 ++++++++++++++++------------ lib/ft8/foxgen.f90 | 3 ++- lib/ft8/foxgen_wrap.f90 | 2 +- widgets/mainwindow.cpp | 10 ++++++++-- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst240/fst240sim.f90 index 338c7c6ba..f687036b0 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst240/fst240sim.f90 @@ -67,9 +67,10 @@ program fst240sim nz=nsps*NN txt=nz*dt !Transmission length (s) tt=nsps*dt !Duration of symbols (s) - allocate( c0(0:nmax-1) ) - allocate( c(0:nmax-1) ) - allocate( wave(nmax) ) + nwave=max(nmax,(NN+2)*nsps) + allocate( c0(0:nwave-1) ) + allocate( c(0:nwave-1) ) + allocate( wave(nwave) ) allocate( iwave(nmax) ) bandwidth_ratio=2500.0/(fs/2.0) @@ -108,7 +109,7 @@ program fst240sim fsample=12000.0 icmplx=1 f0=f00+1.5*hmod*baud - call gen_fst240wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) + call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,f0,icmplx,c0,wave) k=nint((xdt+1.0)/dt) if(nsec.eq.15) k=nint((xdt+0.5)/dt) c0=cshift(c0,-k) @@ -117,7 +118,7 @@ program fst240sim do ifile=1,nfiles c=c0 - if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nmax,NZ,fs,delay,fspread) + if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nwave,NZ,fs,delay,fspread) c=sig*c wave=real(c) if(snrdb.lt.90) then @@ -135,7 +136,7 @@ program fst240sim wave=fac*wave endif if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." - iwave=nint(wave) + iwave=nint(wave(:size(iwave))) h=default_header(12000,nmax) if(nmax/12000.le.30) then write(fname,1102) ifile diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 5976f63ad..f6f8824e2 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -68,7 +68,7 @@ contains logical badsync,unpk77_success,single_decode logical first,nohiscall,lwspr,ex - integer*2 iwave(300*12000) + integer*2 iwave(30*60*12000) data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ @@ -748,8 +748,8 @@ contains integer hmod !Modulation index (submode) integer im(1) !For maxloc real candidates(100,4) !Candidate list - real s(18000) !Low resolution power spectrum - real s2(18000) !CCF of s() with 4 tones + real, allocatable :: s(:) !Low resolution power spectrum + real, allocatable :: s2(:) !CCF of s() with 4 tones real xdb(-3:3) !Model 4-tone CCF peaks real minsync data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ @@ -776,6 +776,8 @@ contains inb=nint(fh) endif + nnw=nint(48000.*nsps*2./fs) + allocate (s(nnw)) s=0. !Compute low-resloution power spectrum do i=ina,inb ! noise analysis window includes signal analysis window j0=nint(i*df2/df1) @@ -785,7 +787,8 @@ contains enddo ina=max(ina,1+3*hmod) !Don't run off the ends - inb=min(inb,18000-3*hmod) + inb=min(inb,nnw-3*hmod) + allocate (s2(nnw)) s2=0. do i=ina,inb !Compute CCF of s() and 4 tones s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) @@ -796,7 +799,7 @@ contains ncand=0 candidates=0 if(ia.lt.3) ia=3 - if(ib.gt.18000-2) ib=18000-2 + if(ib.gt.nnw-2) ib=nnw-2 ! Find candidates, using the CLEAN algorithm to remove a model of each one ! from s2() after it has been found. @@ -824,6 +827,7 @@ contains ! On "plotspec" special request, compute Doppler spread for a decoded signal + include 'fst240/fst240_params.f90' complex, allocatable :: cwave(:) !Reconstructed complex signal complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper real,allocatable :: ss(:) !Computed power spectrum of g(t) @@ -835,15 +839,15 @@ contains ncall=ncall+1 nfft=2*nmax - allocate(cwave(0:nmax-1)) + nwave=max(nmax,(NN+2)*nsps) + allocate(cwave(0:nwave-1)) allocate(g(0:nfft-1)) wave=0 fsample=12000.0 - nsym=160 - call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc,1,cwave,wave) + call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave) cwave=cshift(cwave,-i0*ndown) fac=1.0/32768 - g(0:nmax-1)=fac*float(iwave)*conjg(cwave) + g(0:nmax-1)=fac*float(iwave)*conjg(cwave(:nmax-1)) g(nmax:)=0. call four2a(g,nfft,1,-1,1) !Forward c2c FFT @@ -861,7 +865,7 @@ contains allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz sum1=0. sum2=0. - ns=0 + nns=0 do i=-ia,ia j=i if(j.lt.0) j=i+nfft @@ -869,12 +873,12 @@ contains f=i*df if(f.ge.-4.0 .and. f.le.-2.0) then sum1=sum1 + ss(i) !Power between -2 and -4 Hz - ns=ns+1 + nns=nns+1 else if(f.ge.2.0 .and. f.le.4.0) then sum2=sum2 + ss(i) !Power between +2 and +4 Hz endif enddo - avg=min(sum1/ns,sum2/ns) !Compute avg from smaller sum + avg=min(sum1/nns,sum2/nns) !Compute avg from smaller sum sum1=0. do i=-ia,ia diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 703da0ef9..5aa114ac4 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -15,7 +15,8 @@ subroutine foxgen() ! common block. parameter (NN=79,ND=58,NSPS=4*1920) - parameter (NWAVE=14278656,NFFT=614400,NH=NFFT/2) + parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST240-1800) + parameter (NFFT=614400,NH=NFFT/2) character*40 cmsg character*37 msg,msgsent integer itone(79) diff --git a/lib/ft8/foxgen_wrap.f90 b/lib/ft8/foxgen_wrap.f90 index bc8c430f7..eb489cccc 100644 --- a/lib/ft8/foxgen_wrap.f90 +++ b/lib/ft8/foxgen_wrap.f90 @@ -1,7 +1,7 @@ subroutine foxgen_wrap(msg40,msgbits,itone) parameter (NN=79,ND=58,KK=77,NSPS=4*1920) - parameter (NWAVE=NN*NSPS) + parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST240-1800) character*40 msg40,cmsg character*12 mycall12 diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 2487e7a46..b315c013b 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -428,7 +428,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); - ui->sbTR_FST240W->values ({15, 30, 60, 120, 300}); + ui->sbTR_FST240W->values ({15, 30, 60, 120, 300, 900, 1800}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -3556,6 +3556,8 @@ void MainWindow::guiUpdate() if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0; if(m_TRperiod==300) txDuration=1.0 + 160*21504/12000.0; + if(m_TRperiod==900) txDuration=1.0 + 160*66560/12000.0; + if(m_TRperiod==1800) txDuration=1.0 + 160*134400/12000.0; } if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 @@ -3888,6 +3890,8 @@ void MainWindow::guiUpdate() if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; if(m_TRperiod==300) nsps=21504; + if(m_TRperiod==900) nsps=66560; + if(m_TRperiod==1800) nsps=134400; nsps=4*nsps; //48000 Hz sampling int nsym=160; float fsample=48000.0; @@ -5838,7 +5842,7 @@ void MainWindow::on_actionFST240_triggered() // 0123456789012345678901234567890123 displayWidgets(nWidgets("1111110001001111000100000001000000")); setup_status_bar (bVHF); - ui->sbTR->values ({15, 30, 60, 120, 300}); + ui->sbTR->values ({15, 30, 60, 120, 300, 900, 1800}); on_sbTR_valueChanged (ui->sbTR->value()); ui->cbAutoSeq->setChecked(true); m_wideGraph->setMode(m_mode); @@ -7183,6 +7187,8 @@ void MainWindow::transmit (double snr) if(m_TRperiod==60) nsps=3888; if(m_TRperiod==120) nsps=8200; if(m_TRperiod==300) nsps=21504; + if(m_TRperiod==900) nsps=66560; + if(m_TRperiod==1800) nsps=134400; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; double f0=ui->WSPRfreqSpinBox->value() - m_XIT + 1.5*dfreq; From 8b35e744d0e98160856cb8f221ad959cb921b4ac Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 18 Jul 2020 10:35:26 +0100 Subject: [PATCH 182/239] Increase Tx waveform storage & update wide graph nsps for FST240 --- commons.h | 2 +- lib/ft8/foxgen.f90 | 2 +- widgets/plotter.cpp | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/commons.h b/commons.h index 140c69c6d..0a3872048 100644 --- a/commons.h +++ b/commons.h @@ -85,7 +85,7 @@ extern struct { } echocom_; extern struct { - float wave[14278656]; + float wave[(160+2)*134400*4]; /* (nsym+2)*nsps scaled up to 48kHz */ int nslots; int nfreq; int i3bit[5]; diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 5aa114ac4..13299da89 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -15,7 +15,7 @@ subroutine foxgen() ! common block. parameter (NN=79,ND=58,NSPS=4*1920) - parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST240-1800) + parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST240-1800 at 48kHz) parameter (NFFT=614400,NH=NFFT/2) character*40 cmsg character*37 msg,msgsent diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 160f55b10..5853e07f6 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -420,6 +420,8 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_TRperiod==60) nsps=4000; if(m_TRperiod==120) nsps=8400; if(m_TRperiod==300) nsps=21504; + if(m_TRperiod==900) nsps=66560; + if(m_TRperiod==1800) nsps=134400; float baud=12000.0/nsps; bw=3.0*h*baud; } From 0de538c7237551340d0a54d0be4bb4f4407e8e11 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 18 Jul 2020 12:17:21 +0100 Subject: [PATCH 183/239] Close orphaned jt9 sub-process before restarting --- main.cpp | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index 040225352..b3de449f6 100644 --- a/main.cpp +++ b/main.cpp @@ -353,14 +353,41 @@ int main(int argc, char *argv[]) // Multiple instances: use rig_name as shared memory key mem_jt9.setKey(a.applicationName ()); - if(!mem_jt9.attach()) { - if (!mem_jt9.create(sizeof(struct dec_data))) { - splash.hide (); - MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"), - a.translate ("main", "Unable to create shared memory segment")); - throw std::runtime_error {"Shared memory error"}; + // try and shut down any orphaned jt9 process + for (int i = 3; i; --i) // three tries to close old jt9 + { + if (mem_jt9.attach ()) // shared memory presence implies + // orphaned jt9 sub-process + { + dec_data_t * dd = reinterpret_cast (mem_jt9.data()); + mem_jt9.lock (); + dd->ipc[1] = 999; // tell jt9 to shut down + mem_jt9.unlock (); + mem_jt9.detach (); // start again + } + else + { + break; // good to go + } + QThread::sleep (1); // wait for jt9 to end + } + if (!mem_jt9.attach ()) + { + if (!mem_jt9.create (sizeof (struct dec_data))) + { + splash.hide (); + MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"), + a.translate ("main", "Unable to create shared memory segment")); + throw std::runtime_error {"Shared memory error"}; + } + } + else + { + splash.hide (); + MessageBox::critical_message (nullptr, a.translate ("main", "Sub-process error"), + a.translate ("main", "Failed to close orphaned jt9 process")); + throw std::runtime_error {"Sub-process error"}; } - } mem_jt9.lock (); memset(mem_jt9.data(),0,sizeof(struct dec_data)); //Zero all decoding params in shared memory mem_jt9.unlock (); From 98596a4be7ab8ab8d7f1f9131f7dba610a878476 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 18 Jul 2020 09:02:11 -0500 Subject: [PATCH 184/239] Choose nfft1 and ndown so that both nfft1 and nfft2 have small prime factors. --- lib/fst240_decode.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 5976f63ad..9d3441e1d 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -175,7 +175,7 @@ contains nsps=1680 nmax=30*12000 ndown=42/hmod !nss=40,80,168,336 - nfft1=359856 + nfft1=359856 !nfft2=8568=2^3*3^2*7*17 if(hmod.eq.4) then ndown=10 nfft1=nmax @@ -189,28 +189,28 @@ contains nmax=60*12000 ndown=96/hmod !nss=36,81,162,324 if(hmod.eq.1) ndown=108 - nfft1=int(719808/ndown)*ndown + nfft1=7500*96 ! nfft2=7500=2^2*3*5^4 else if(ntrperiod.eq.120) then nsps=8200 nmax=120*12000 ndown=200/hmod !nss=40,82,164,328 if(hmod.eq.1) ndown=205 - nfft1=int(nmax/ndown)*ndown + nfft1=7200*200 ! nfft2=7200=2^5*3^2*5^2 else if(ntrperiod.eq.300) then nsps=21504 nmax=300*12000 ndown=512/hmod !nss=42,84,168,336 - nfft1=int((nmax-200)/ndown)*ndown + nfft1=7020*512 ! nfft2=7020=2^2*3^3*5*13 else if(ntrperiod.eq.900) then nsps=66560 nmax=900*12000 ndown=1664/hmod !nss=40,80,160,320 - nfft1=int((nmax-200)/ndown)*ndown + nfft1=6480*1664 ! nfft2=6480=2^4*3^4*5 else if(ntrperiod.eq.1800) then nsps=134400 nmax=1800*12000 ndown=3360/hmod !nss=40,80,160,320 - nfft1=int((nmax-200)/ndown)*ndown + nfft1=6426*3360 ! nfft2=6426=2*3^3*7*17 end if nss=nsps/ndown fs=12000.0 !Sample rate From 9e6d31dff313e66a46f0ae8c87f2d31c7257945c Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 18 Jul 2020 18:49:20 +0100 Subject: [PATCH 185/239] Debug print of shared memory size --- main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index b3de449f6..43543ce59 100644 --- a/main.cpp +++ b/main.cpp @@ -373,13 +373,14 @@ int main(int argc, char *argv[]) } if (!mem_jt9.attach ()) { - if (!mem_jt9.create (sizeof (struct dec_data))) + if (!mem_jt9.create (sizeof (dec_data))) { splash.hide (); MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"), a.translate ("main", "Unable to create shared memory segment")); throw std::runtime_error {"Shared memory error"}; } + qDebug () << "shmem size:" << mem_jt9.size (); } else { From 60ddd400496c3a7775a1f21e88ecb7e42da5678b Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 18 Jul 2020 18:50:08 +0100 Subject: [PATCH 186/239] More 15 & 30 minute T.R period updates --- widgets/mainwindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b315c013b..93f273f18 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1343,13 +1343,15 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST240" or m_mode=="FST240W") { - int stop[] = {39,85,187,387,1003}; - int stop_EME[] = {48,95,197,396,1012}; + int stop[] = {39,85,187,387,1003,3092,6233}; + int stop_EME[] = {48,95,197,396,1012,3102,6243}; int i=0; if(m_TRperiod==30) i=1; if(m_TRperiod==60) i=2; if(m_TRperiod==120) i=3; if(m_TRperiod==300) i=4; + if(m_TRperiod==900) i=5; + if(m_TRperiod==1800) i=5; if(m_config.decode_at_52s()) { m_hsymStop=stop_EME[i]; } else { From 43d6eacc4bb4039e9be37ca8da90d370f5812c06 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 18 Jul 2020 18:52:09 +0100 Subject: [PATCH 187/239] Refined stop times --- widgets/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 93f273f18..c28870d0a 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1343,8 +1343,8 @@ void MainWindow::fixStop() } else if (m_mode=="FT4") { m_hsymStop=21; } else if(m_mode=="FST240" or m_mode=="FST240W") { - int stop[] = {39,85,187,387,1003,3092,6233}; - int stop_EME[] = {48,95,197,396,1012,3102,6243}; + int stop[] = {39,85,187,387,1003,3107,6232}; + int stop_EME[] = {48,95,197,396,1012,3107,6232}; int i=0; if(m_TRperiod==30) i=1; if(m_TRperiod==60) i=2; From e73f27954dbf63b4c851254210d073ab6f0bc2b3 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 18 Jul 2020 13:55:33 -0400 Subject: [PATCH 188/239] Increase valid range of TRperiod controls. --- widgets/mainwindow.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index ef5a882b1..a3b9fe7cf 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -1013,7 +1013,7 @@ When not checked you can view the calibration results. 5 - 30 + 1800 30 @@ -2120,10 +2120,10 @@ list. The list can be maintained in Settings (F2). T/R - 120 + 15 - 300 + 1800 From 4fa9557272b41dc5a2ad30780408c1755d1e5298 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 18 Jul 2020 13:56:19 -0400 Subject: [PATCH 189/239] Add end-of-Rx-sequence number of buffers for 900 and 1800 s sequences. --- widgets/mainwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b315c013b..f18b9fd73 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -427,7 +427,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, add_child_to_event_filter (this); ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); - ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); + ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300, 900, 1800}); ui->sbTR_FST240W->values ({15, 30, 60, 120, 300, 900, 1800}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -1573,6 +1573,7 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int 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 { + qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz"); // // This member function runs in a thread and should not access // members that may be changed in the GUI thread or any other thread @@ -1609,6 +1610,7 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int { return file_name + ": " + wav.errorString (); } + qDebug() << "bb" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz"); return QString {}; } From 58fc82e178d2d45585850a0f2e015e32c9cb2dd7 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 19 Jul 2020 12:31:10 +0100 Subject: [PATCH 190/239] Correct standard message generation for FST240 --- widgets/mainwindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 3a3bbd1ea..ea11d94d8 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5147,7 +5147,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") { + if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4" || m_mode=="FST240") { QString t2,t3; QString sent=rpt; QString rs,rst; @@ -5227,7 +5227,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } t=t0 + (m_send_RR73 ? "RR73" : "RRR"); - if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4") { + if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST240") { if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> " + (m_send_RR73 ? "RR73" : "RRR"); if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " " + (m_send_RR73 ? "RR73" : "RRR"); } @@ -5235,7 +5235,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) msgtype(t, ui->tx4); t=t0 + "73"; - if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4") { + if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST240") { if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> 73"; if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " 73"; } @@ -5251,7 +5251,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144") return; + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144" || m_mode == "FST240") return; if (is_compound) { if (is_type_one) { @@ -5266,7 +5266,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) if (!eme_short_codes) { if((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4") && SpecOp::NA_VHF == m_config.special_op_id()) { - msgtype(t + "R " + my_grid, ui->tx3); + msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code } else { msgtype(t + "R" + rpt, ui->tx3); } @@ -5295,7 +5295,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) if (!eme_short_codes) { if ((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4") && SpecOp::NA_VHF == m_config.special_op_id()) { - msgtype(t + "R " + my_grid, ui->tx3); + msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code msgtype(t + "RRR", ui->tx4); } else { msgtype(t0 + "R" + rpt, ui->tx3); From 159b8a97f74b50673f3589081d0254410f39ac5c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 19 Jul 2020 13:20:41 -0400 Subject: [PATCH 191/239] Better handling of fSpread in mainwindow.cpp. Makes auto-seq work when plotspec is used. --- lib/decoder.f90 | 18 +++++++++++------- widgets/mainwindow.cpp | 21 ++++++++++++++++----- widgets/mainwindow.h | 3 ++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 27c49a82c..bb7aaaa8e 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -719,6 +719,7 @@ contains character*2 annot character*37 decoded0 + character*70 line decoded0=decoded annot=' ' @@ -728,22 +729,25 @@ contains endif if(ntrperiod.lt.60) then - write(*,1001) nutc,nsnr,dt,nint(freq),decoded0,annot + write(line,1001) nutc,nsnr,dt,nint(freq),decoded0,annot 1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') else - if(fmid.ne.-999.0) then - if(w50.lt.0.95) write(decoded0(18:22),'(f5.3)') w50 - if(w50.ge.0.95) write(decoded0(18:22),'(f5.2)') w50 - if(decoded0(18:18).eq.'0') decoded0(18:18)=' ' - endif - write(*,1003) nutc,nsnr,dt,nint(freq),decoded0,annot + write(line,1003) nutc,nsnr,dt,nint(freq),decoded0,annot 1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2,2f7.3) write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') endif + if(fmid.ne.-999.0) then + if(w50.lt.0.95) write(line(65:70),'(f6.3)') w50 + if(w50.ge.0.95) write(line(65:70),'(f6.2)') w50 + endif + + write(*,1005) line +1005 format(a70) + call flush(6) call flush(13) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 3a3bbd1ea..e45a8a90f 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1575,7 +1575,6 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int 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 { - qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz"); // // This member function runs in a thread and should not access // members that may be changed in the GUI thread or any other thread @@ -1612,7 +1611,6 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int { return file_name + ": " + wav.errorString (); } - qDebug() << "bb" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz"); return QString {}; } @@ -3147,6 +3145,8 @@ void MainWindow::readFromStdout() //readFromStdout { while(proc_jt9.canReadLine()) { auto line_read = proc_jt9.readLine (); + m_fSpread=line_read.mid(64,6).toFloat(); + line_read=line_read.left(64); if (auto p = std::strpbrk (line_read.constData (), "\n\r")) { // truncate before line ending chars line_read = line_read.left (p - line_read.constData ()); @@ -3231,7 +3231,18 @@ void MainWindow::readFromStdout() //readFromStdout m_bDisplayedOnce=true; } } else { - ui->decodedTextBrowser->displayDecodedText(decodedtext0,m_baseCall,m_mode,m_config.DXCC(), + DecodedText decodedtext1=decodedtext0; + if(m_mode.startsWith("FST240") and m_fSpread>0.0) { + QString t=decodedtext0.string(); + QString t2; + if(m_fSpread<0.95) t2.sprintf("%5.3f",m_fSpread); + if(m_fSpread>=0.95) t2.sprintf("%5.2f",m_fSpread); + t=t.left(46)+t2+t.mid(50); + t=t.trimmed(); + DecodedText dt2{t}; + decodedtext1=dt2; + } + ui->decodedTextBrowser->displayDecodedText(decodedtext1,m_baseCall,m_mode,m_config.DXCC(), m_logBook,m_currentBand,m_config.ppfx(), (ui->cbCQonly->isVisible() and ui->cbCQonly->isChecked())); @@ -3476,7 +3487,6 @@ void MainWindow::pskPost (DecodedText const& decodedtext) int snr = decodedtext.snr(); Frequency frequency = m_freqNominal + audioFrequency; pskSetLocal (); -// qDebug() << "bb" << deCall << grid << frequency << msgmode << snr; if(grid.contains (grid_regexp)) { // qDebug() << "To PSKreporter:" << deCall << grid << frequency << msgmode << snr; psk_Reporter->addRemoteStation(deCall,grid,QString::number(frequency),msgmode, @@ -4529,7 +4539,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie || ("JT9" == m_mode && mode != "@") || ("MSK144" == m_mode && !("&" == mode || "^" == mode)) || ("QRA64" == m_mode && mode.left (1) != ":")) { - return; //Currently we do auto-sequencing only in FT4, FT8, and MSK144 + return; //Currently we do auto-sequencing only in FT4, FT8, MSK144, and FST240 } //Skip the rest if no decoded text extracted @@ -4570,6 +4580,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie QString hiscall; QString hisgrid; message.deCallAndGrid(/*out*/hiscall,hisgrid); + if(message.string().contains(hiscall+"/R")) { hiscall+="/R"; ui->dxCallEntry->setText(hiscall); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 3653cfd5c..630935ac8 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -419,6 +419,7 @@ private: float m_t0Pick; float m_t1Pick; float m_fCPUmskrtd; + float m_fSpread; qint32 m_waterfallAvg; qint32 m_ntx; @@ -716,7 +717,7 @@ private: void pskPost(DecodedText const& decodedtext); void displayDialFrequency (); void transmitDisplay (bool); - void processMessage(DecodedText const&, Qt::KeyboardModifiers = Qt::NoModifier); + void processMessage(DecodedText const& message, Qt::KeyboardModifiers = Qt::NoModifier); void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence, quint8 modifiers); void locationChange(QString const& location); void replayDecodes (); From 731dfc5c6f5d793827ec1153d1da16df4cc89a2b Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 19 Jul 2020 21:09:52 +0100 Subject: [PATCH 192/239] Qt 5.15 compatibility --- widgets/mainwindow.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 2e8b8aa9e..9c1825f27 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3234,12 +3234,7 @@ void MainWindow::readFromStdout() //readFromStdout DecodedText decodedtext1=decodedtext0; if(m_mode.startsWith("FST240") and m_fSpread>0.0) { QString t=decodedtext0.string(); - QString t2; - if(m_fSpread<0.95) t2.sprintf("%5.3f",m_fSpread); - if(m_fSpread>=0.95) t2.sprintf("%5.2f",m_fSpread); - t=t.left(46)+t2+t.mid(50); - t=t.trimmed(); - DecodedText dt2{t}; + DecodedText dt2 {QString {"%1%2%3"}.arg (t.left (46)).arg (m_fSpread, 5, 'f', m_fSpread < 0.95 ? 2 : 3).arg (t.mid(50)).trimmed ()}; decodedtext1=dt2; } ui->decodedTextBrowser->displayDecodedText(decodedtext1,m_baseCall,m_mode,m_config.DXCC(), From 22f66795a1b32a07849479dced12e9847c2d5b1c Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 20 Jul 2020 15:15:55 +0100 Subject: [PATCH 193/239] Improved C/Fortran string interoperation, and fix azel.dat updates The azel.dat file is no longer written with future Doppler correction information designed for rigs that can't do CAT QSY commands while transmitting. --- CMakeLists.txt | 2 + lib/astrosub.f90 | 48 ++-- lib/c_interface_module.f90 | 441 +++++++++++++++++++++++++++++++++++++ lib/types.f90 | 10 + widgets/astro.cpp | 24 +- 5 files changed, 482 insertions(+), 43 deletions(-) create mode 100644 lib/c_interface_module.f90 create mode 100644 lib/types.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 80199358d..d2ed2459b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -358,6 +358,8 @@ endif (WIN32) set (wsjt_FSRCS # put module sources first in the hope that they get rebuilt before use + lib/types.f90 + lib/C_interface_module.f90 lib/shmem.f90 lib/crc.f90 lib/fftw3mod.f90 diff --git a/lib/astrosub.f90 b/lib/astrosub.f90 index 0670d66dc..5e7f473f0 100644 --- a/lib/astrosub.f90 +++ b/lib/astrosub.f90 @@ -1,5 +1,4 @@ module astro_module - use, intrinsic :: iso_c_binding, only : c_int, c_double, c_bool, c_char, c_ptr, c_size_t, c_f_pointer implicit none private @@ -7,50 +6,37 @@ module astro_module contains - subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid_cp,mygrid_len, & - hisgrid_cp,hisgrid_len,AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8, & + subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid_cp, & + hisgrid_cp,AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8, & ntsky,ndop,ndop00,RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8,techo8,width1, & - width2,bTx,AzElFileName_cp,AzElFileName_len,jpleph_cp,jpleph_len) & + width2,bTx,AzElFileName_cp,jpleph_file_name_cp) & bind (C, name="astrosub") - integer, parameter :: dp = selected_real_kind(15, 50) + use :: types, only: dp + use :: C_interface_module, only: C_int, C_double, C_bool, C_ptr, C_string_value, assignment(=) - integer(c_int), intent(in), value :: nyear, month, nday - real(c_double), intent(in), value :: uth8, freq8 - real(c_double), intent(out) :: AzSun8, ElSun8, AzMoon8, ElMoon8, AzMoonB8, & + integer(C_int), intent(in), value :: nyear, month, nday + real(C_double), intent(in), value :: uth8, freq8 + real(C_double), intent(out) :: AzSun8, ElSun8, AzMoon8, ElMoon8, AzMoonB8, & ElMoonB8, Ramoon8, DecMoon8, Dgrd8, poloffset8, xnr8, techo8, width1, & width2 - integer(c_int), intent(out) :: ntsky, ndop, ndop00 - logical(c_bool), intent(in), value :: bTx - type(c_ptr), intent(in), value :: mygrid_cp, hisgrid_cp, AzElFileName_cp, jpleph_cp - integer(c_size_t), intent(in), value :: mygrid_len, hisgrid_len, AzElFileName_len, jpleph_len + integer(C_int), intent(out) :: ntsky, ndop, ndop00 + logical(C_bool), intent(in), value :: bTx + type(C_ptr), value, intent(in) :: mygrid_cp, hisgrid_cp, AzElFileName_cp, & + jpleph_file_name_cp character(len=6) :: mygrid, hisgrid - character(kind=c_char, len=:), allocatable :: AzElFileName + character(len=:), allocatable :: AzElFileName character(len=1) :: c1 integer :: ih, im, imin, is, isec, nfreq, nRx real(dp) :: AzAux, ElAux, dbMoon8, dfdt, dfdt0, doppler, doppler00, HA8, sd8, xlst8 character*256 jpleph_file_name common/jplcom/jpleph_file_name - block - character(kind=c_char, len=mygrid_len), pointer :: mygrid_fp - character(kind=c_char, len=hisgrid_len), pointer :: hisgrid_fp - character(kind=c_char, len=AzElFileName_len), pointer :: AzElFileName_fp - character(kind=c_char, len=jpleph_len), pointer :: jpleph_fp - call c_f_pointer(cptr=mygrid_cp, fptr=mygrid_fp) - mygrid = mygrid_fp - mygrid_fp => null() - call c_f_pointer(cptr=hisgrid_cp, fptr=hisgrid_fp) - hisgrid = hisgrid_fp - hisgrid_fp => null() - call c_f_pointer(cptr=AzElFileName_cp, fptr=AzElFileName_fp) - AzElFileName = AzElFileName_fp - AzElFileName_fp => null() - call c_f_pointer(cptr=jpleph_cp, fptr=jpleph_fp) - jpleph_file_name = jpleph_fp - jpleph_fp => null() - end block + mygrid = mygrid_cp + hisgrid = hisgrid_cp + AzElFileName = C_string_value (AzElFileName_cp) + jpleph_file_name = jpleph_file_name_cp call astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, & AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, & diff --git a/lib/c_interface_module.f90 b/lib/c_interface_module.f90 new file mode 100644 index 000000000..47fee9de4 --- /dev/null +++ b/lib/c_interface_module.f90 @@ -0,0 +1,441 @@ +! FILE: c_interface_module.f90 +! PURPOSE: Supplement ISO-C-Binding to provide type aliases and interfaces +! to common ISO-C string functions to aid working with strings. +! AUTHOR: Joseph M. Krahn +! STATUS: Still in development. Reasonably complete, but somewhat limited testing. +! +! The idea is to provide type aliases for all ISO-C types, so that the +! Fortran interface code more explicitly defines the actual C interface. +! This should be updated to support F2008 variable-length allocatable +! strings. +! +! Entity names all have the "C_" prefix, as with ISO-C-Binding, with a +! few exceptions. +! +! Sourced from: http://fortranwiki.org/fortran/show/c_interface_module +! +! One FORALL statement reverted to a DO loop to avoid a gfortran 4.9.2 ICE +! +module C_interface_module + use, intrinsic :: ISO_C_Binding, & + ! C type aliases for pointer derived types: + C_ptr => C_ptr , & + C_char_ptr => C_ptr, & + C_const_char_ptr => C_ptr, & + C_void_ptr => C_ptr, & + C_const_void_ptr => C_ptr + + implicit none + public + + !---------------------------------------------------------------------------- + ! C type aliases for intrinsic type KIND parameters: + + ! NOTE: a C enum may not always be a standard C int + integer, parameter :: C_enum = C_int + + ! Defining off_t is difficult, because it may depend on "LARGEFILE" selection. + ! integer, parameter :: C_off_t = ?? + + ! C string terminator alais using the 3-letter ASCII name. + ! The C_ prefix is not used because it is just an ASCII character. + character(len=1,kind=C_char), parameter :: NUL = C_NULL_char + + ! NOTE: In C, "char" is distinct from "signed char", unlike integers. + ! The plain "char" type is specific for text/string values, whereas + ! "signed char" should indicate 1-byte integer data. + ! + ! Most ISO-C systems have wide chars "wchar_t", but Fortran compilers + ! have limited support for different character kinds. UTF encoding + ! adds more complexity. This should be updated as Fortran compilers + ! include support for more character types. + ! + + ! Fortran does not (yet) support unsigned types. + integer, parameter :: & + C_unsigned = C_int, & + C_unsigned_short = C_short, & + C_unsigned_long = C_long, & + C_unsigned_long_long = C_long_long, & + C_unsigned_char = C_signed_char, & + C_ssize_t = C_size_t, & + C_uint8_t = C_int8_t, & + C_uint16_t = C_int16_t, & + C_uint32_t = C_int32_t, & + C_uint64_t = C_int64_t, & + C_uint_least8_t = C_int_least8_t, & + C_uint_least16_t = C_int_least16_t, & + C_uint_least32_t = C_int_least32_t, & + C_uint_least64_t = C_int_least64_t, & + C_uint_fast8_t = C_int_fast8_t, & + C_uint_fast16_t = C_int_fast16_t, & + C_uint_fast32_t = C_int_fast32_t, & + C_uint_fast64_t = C_int_fast64_t, & + C_uintmax_t = C_intmax_t + ! Note: ptrdiff_t cannot be reliably defined from other types. + ! When practical, it is larger than a pointer because it benefits + ! from the full unsigned range in both positive and negative directions. + + ! Integer versions including 'int', where the 'int' is optional: + integer, parameter :: & + C_short_int = C_short, & + C_long_int = C_long, & + C_long_long_int = C_long_long, & + C_unsigned_int = C_unsigned, & + C_unsigned_short_int = C_short, & + C_unsigned_long_int = C_long, & + C_unsigned_long_long_int = C_long_long + + interface C_F_string + module procedure C_F_string_ptr + module procedure C_F_string_chars + end interface C_F_string + + interface F_C_string + module procedure F_C_string_ptr + module procedure F_C_string_chars + end interface F_C_string + + !======================================================================= + ! Some useful ISO C library string functions from + ! These are based on GCC header sections marked as NAMESPACE_STD + interface + + ! Copy N bytes of SRC to DEST, no aliasing or overlapping allowed. + ! extern void *memcpy (void *dest, const void *src, size_t n); + function C_memcpy(dest, src, n) result(result) bind(C,name="memcpy") + import C_void_ptr, C_size_t + type(C_void_ptr) :: result + type(C_void_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_void_ptr), value, intent(in) :: src ! target=intent(in) + integer(C_size_t), value, intent(in) :: n + end function C_memcpy + + ! Copy N bytes of SRC to DEST, guaranteeing correct behavior for overlapping strings. + !extern void *memmove (void *dest, const void *src, size_t n) + function C_memmove(dest, src, n) result(result) bind(C,name="memmove") + import C_void_ptr, C_size_t + type(C_void_ptr) :: result + type(C_void_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_void_ptr), value, intent(in) :: src + integer(C_size_t), value, intent(in) :: n + end function C_memmove + + ! Set N bytes of S to C. + !extern void *memset (void *s, int c, size_t n) + function C_memset(s, c, n) result(result) bind(C,name="memset") + import C_void_ptr, C_int, C_size_t + type(C_void_ptr) :: result + type(C_void_ptr), value, intent(in) :: s ! target=intent(out) + integer(C_int), value, intent(in) :: c + integer(C_size_t), value, intent(in) :: n + end function C_memset + + ! Compare N bytes of S1 and S2. + !extern int memcmp (const void *s1, const void *s2, size_t n) + pure function C_memcmp(s1, s2, n) result(result) bind(C,name="memcmp") + import C_int, C_void_ptr, C_size_t + integer(C_int) :: result + type(C_void_ptr), value, intent(in) :: s1 + type(C_void_ptr), value, intent(in) :: s2 + integer(C_size_t), value, intent(in) :: n + end function C_memcmp + + ! Search N bytes of S for C. + !extern void *memchr (const void *s, int c, size_t n) + pure function C_memchr(s, c, n) result(result) bind(C,name="memchr") + import C_void_ptr, C_int, C_size_t + type(C_void_ptr) :: result + type(C_void_ptr), value, intent(in) :: s + integer(C_int), value, intent(in) :: c + integer(C_size_t), value, intent(in) :: n + end function C_memchr + + ! Copy SRC to DEST. + !extern char *strcpy (char *dest, const char *src) + function C_strcpy(dest, src) result(result) bind(C,name="strcpy") + import C_char_ptr, C_size_t + type(C_char_ptr) :: result + type(C_char_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_char_ptr), value, intent(in) :: src + end function C_strcpy + + ! Copy no more than N characters of SRC to DEST. + !extern char *strncpy (char *dest, const char *src, size_t n) + function C_strncpy(dest, src, n) result(result) bind(C,name="strncpy") + import C_char_ptr, C_size_t + type(C_char_ptr) :: result + type(C_char_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_char_ptr), value, intent(in) :: src + integer(C_size_t), value, intent(in) :: n + end function C_strncpy + + ! Append SRC onto DEST. + !extern char *strcat (char *dest, const char *src) + function C_strcat(dest, src) result(result) bind(C,name="strcat") + import C_char_ptr, C_size_t + type(C_char_ptr) :: result + type(C_char_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_char_ptr), value, intent(in) :: src + end function C_strcat + + ! Append no more than N characters from SRC onto DEST. + !extern char *strncat (char *dest, const char *src, size_t n) + function C_strncat(dest, src, n) result(result) bind(C,name="strncat") + import C_char_ptr, C_size_t + type(C_char_ptr) :: result + type(C_char_ptr), value, intent(in) :: dest ! target=intent(out) + type(C_char_ptr), value, intent(in) :: src + integer(C_size_t), value, intent(in) :: n + end function C_strncat + + ! Compare S1 and S2. + !extern int strcmp (const char *s1, const char *s2) + pure function C_strcmp(s1, s2) result(result) bind(C,name="strcmp") + import C_int, C_char_ptr, C_size_t + integer(C_int) :: result + type(C_char_ptr), value, intent(in) :: s1 + type(C_char_ptr), value, intent(in) :: s2 + end function C_strcmp + + ! Compare N characters of S1 and S2. + !extern int strncmp (const char *s1, const char *s2, size_t n) + pure function C_strncmp(s1, s2, n) result(result) bind(C,name="strncmp") + import C_int, C_char_ptr, C_size_t + integer(C_int) :: result + type(C_char_ptr), value, intent(in) :: s1 + type(C_char_ptr), value, intent(in) :: s2 + integer(C_size_t), value, intent(in) :: n + end function C_strncmp + + ! Return the length of S. + !extern size_t strlen (const char *s) + pure function C_strlen(s) result(result) bind(C,name="strlen") + import C_char_ptr, C_size_t + integer(C_size_t) :: result + type(C_char_ptr), value, intent(in) :: s !character(len=*), intent(in) + end function C_strlen + + end interface + + ! End of + !========================================================================= + ! Standard ISO-C malloc routines: + interface + + ! void *calloc(size_t nmemb, size_t size); + type(C_void_ptr) function C_calloc(nmemb, size) bind(C,name="calloc") + import C_void_ptr, C_size_t + integer(C_size_t), value, intent(in) :: nmemb, size + end function C_calloc + + ! void *malloc(size_t size); + type(C_void_ptr) function C_malloc(size) bind(C,name="malloc") + import C_void_ptr, C_size_t + integer(C_size_t), value, intent(in) :: size + end function C_malloc + + ! void free(void *ptr); + subroutine C_free(ptr) bind(C,name="free") + import C_void_ptr + type(C_void_ptr), value, intent(in) :: ptr + end subroutine C_free + + ! void *realloc(void *ptr, size_t size); + type(C_void_ptr) function C_realloc(ptr,size) bind(C,name="realloc") + import C_void_ptr, C_size_t + type(C_void_ptr), value, intent(in) :: ptr + integer(C_size_t), value, intent(in) :: size + end function C_realloc + + end interface + + interface assignment(=) + module procedure F_string_assign_C_string + end interface assignment(=) + + !========================================================================== + +contains + + ! HACK: For some reason, C_associated was not defined as pure. + pure logical function C_associated_pure(ptr) result(associated) + type(C_ptr), intent(in) :: ptr + integer(C_intptr_t) :: iptr + iptr = transfer(ptr,iptr) + associated = (iptr /= 0) + end function C_associated_pure + + ! Set a fixed-length Fortran string to the value of a C string. + subroutine F_string_assign_C_string(F_string, C_string) + character(len=*), intent(out) :: F_string + type(C_ptr), intent(in) :: C_string + character(len=1,kind=C_char), pointer :: p_chars(:) + integer :: i + if (.not. C_associated(C_string) ) then + F_string = ' ' + else + call C_F_pointer(C_string,p_chars,[huge(0)]) + i=1 + do while(p_chars(i)/=NUL .and. i<=len(F_string)) + F_string(i:i) = p_chars(i) + i=i+1 + end do + if (idata_dir ().absoluteFilePath ("JPLEPH"); astrosub(nyear, month, nday, uth, static_cast (freq_moon), - mygrid.toLatin1 ().constData (), mygrid.size (), - hisgrid.toLatin1().constData(), hisgrid.size (), + mygrid.toLatin1 ().data (), + hisgrid.toLatin1().data(), &azsun, &elsun, &azmoon, &elmoon, &azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon, &dgrd, &poloffset, &xnr, &techo, &width1, &width2, bTx, - AzElFileName.toLatin1().constData(), AzElFileName.size (), - jpleph.toLatin1().constData(), jpleph.size ()); + AzElFileName.toLatin1().data(), + jpleph.toLatin1().data()); if(!hisgrid.size ()) { azmoondx=0.0; @@ -224,14 +224,14 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const double sec {target_date_time.time().second() + 0.001*target_date_time.time().msec()}; double uth {nhr + nmin/60.0 + sec/3600.0}; astrosub(nyear, month, nday, uth, static_cast (freq_moon), - mygrid.toLatin1 ().constData (), mygrid.size (), - hisgrid.toLatin1().constData(), hisgrid.size (), + mygrid.toLatin1 ().data (), + hisgrid.toLatin1().data(), &azsun, &elsun, &azmoon, &elmoon, &azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon, &dgrd, &poloffset, &xnr, &techo, &width1, &width2, bTx, - AzElFileName.toLatin1().constData(), AzElFileName.size (), - jpleph.toLatin1().constData(), jpleph.size ()); + nullptr, // don't overwrite azel.dat + jpleph.toLatin1().data()); FrequencyDelta offset {0}; switch (m_DopplerMethod) { From b427a921374af4089762483955e5a59f1c91dc4b Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 20 Jul 2020 11:16:37 -0400 Subject: [PATCH 194/239] Increase max value of Navg spinner on WideGraph. --- widgets/widegraph.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/widegraph.ui b/widgets/widegraph.ui index 7deea52c8..b0165e040 100644 --- a/widgets/widegraph.ui +++ b/widgets/widegraph.ui @@ -393,7 +393,7 @@ 1 - 50 + 500 From 07e06de8f331191ecca2c1cbaf08ecddcb3c19fe Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 20 Jul 2020 11:23:30 -0400 Subject: [PATCH 195/239] Increase gain of the yellow "Linear average" plot. --- widgets/plotter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 5853e07f6..f5cf5c463 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -210,7 +210,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed) for(int k=0; k Date: Mon, 20 Jul 2020 11:29:58 -0400 Subject: [PATCH 196/239] Add Round-Robin options for cycles of 4, 5, and 6 sequences. --- widgets/mainwindow.ui | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index a3b9fe7cf..d43aa62f7 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2187,6 +2187,81 @@ list. The list can be maintained in Settings (F2). 3/3 + + + 1/4 + + + + + 2/4 + + + + + 3/4 + + + + + 4/4 + + + + + 1/5 + + + + + 2/5 + + + + + 3/5 + + + + + 4/5 + + + + + 5/5 + + + + + 1/6 + + + + + 2/6 + + + + + 3/6 + + + + + 4/6 + + + + + 5/6 + + + + + 6/6 + + From d9c2a1182111d20f8084def9816055267d8ccdc0 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 20 Jul 2020 11:48:09 -0400 Subject: [PATCH 197/239] Fix double-clicking on a decode line containing fSpread. --- widgets/mainwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 9c1825f27..4a7ef6f42 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4514,7 +4514,9 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers) } return; } - DecodedText message {cursor.block().text().trimmed().left(61).remove("TU; ")}; + QString t{cursor.block().text().trimmed().left(61).remove("TU; ")}; + t=t.left(46)+" "+t.mid(51); + DecodedText message{t.trimmed()}; m_bDoubleClicked = true; processMessage (message, modifiers); } From 06b97466198c07ceb3ee6a340a2a467f7e2a34f7 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 20 Jul 2020 18:27:29 +0100 Subject: [PATCH 198/239] Make fSpread printing compatible with QSOs --- widgets/displaytext.cpp | 8 +++++++- widgets/displaytext.h | 3 ++- widgets/mainwindow.cpp | 23 ++++++++++++++--------- widgets/mainwindow.h | 1 - 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 5d8136a01..75807c959 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -387,7 +387,8 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons void DisplayText::displayDecodedText(DecodedText const& decodedText, QString const& myCall, QString const& mode, bool displayDXCCEntity, LogBook const& logBook, - QString const& currentBand, bool ppfx, bool bCQonly) + QString const& currentBand, bool ppfx, bool bCQonly, + bool haveFSpread, float fSpread) { m_bPrincipalPrefix=ppfx; QColor bg; @@ -421,6 +422,11 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; if(!dxGrid.contains(grid_regexp)) dxGrid=""; message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info + if (haveFSpread) + { + message += QString {37 - message.size (), QChar {' '}}; + message += QChar::Nbsp + QString {"%1"}.arg (fSpread, 5, 'f', fSpread < 0.95 ? 3 : 2); + } m_CQPriority=""; if (CQcall) { diff --git a/widgets/displaytext.h b/widgets/displaytext.h index d4adc3d2c..fbbfa5656 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -30,7 +30,8 @@ public: void insertLineSpacer(QString const&); void displayDecodedText(DecodedText const& decodedText, QString const& myCall, QString const& mode, bool displayDXCCEntity, LogBook const& logBook, - QString const& currentBand=QString {}, bool ppfx=false, bool bCQonly=false); + QString const& currentBand=QString {}, bool ppfx=false, bool bCQonly=false, + bool haveFSpread = false, float fSpread = 0.); void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode, double TRperiod); void displayQSY(QString text); void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {}); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 9c1825f27..35869b2c5 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3145,12 +3145,21 @@ void MainWindow::readFromStdout() //readFromStdout { while(proc_jt9.canReadLine()) { auto line_read = proc_jt9.readLine (); - m_fSpread=line_read.mid(64,6).toFloat(); - line_read=line_read.left(64); if (auto p = std::strpbrk (line_read.constData (), "\n\r")) { // truncate before line ending chars line_read = line_read.left (p - line_read.constData ()); } + bool haveFSpread {false}; + float fSpread {0.}; + if (m_mode.startsWith ("FST240")) + { + auto text = line_read.mid (64, 6).trimmed (); + if (text.size ()) + { + fSpread = text.toFloat (&haveFSpread); + line_read = line_read.left (64); + } + } if(m_mode!="FT8" and m_mode!="FT4") { //Pad 22-char msg to at least 37 chars line_read = line_read.left(44) + " " + line_read.mid(44); @@ -3232,14 +3241,10 @@ void MainWindow::readFromStdout() //readFromStdout } } else { DecodedText decodedtext1=decodedtext0; - if(m_mode.startsWith("FST240") and m_fSpread>0.0) { - QString t=decodedtext0.string(); - DecodedText dt2 {QString {"%1%2%3"}.arg (t.left (46)).arg (m_fSpread, 5, 'f', m_fSpread < 0.95 ? 2 : 3).arg (t.mid(50)).trimmed ()}; - decodedtext1=dt2; - } ui->decodedTextBrowser->displayDecodedText(decodedtext1,m_baseCall,m_mode,m_config.DXCC(), - m_logBook,m_currentBand,m_config.ppfx(), - (ui->cbCQonly->isVisible() and ui->cbCQonly->isChecked())); + m_logBook,m_currentBand,m_config.ppfx(), + ui->cbCQonly->isVisible() && ui->cbCQonly->isChecked(), + haveFSpread, fSpread); if(m_bBestSPArmed and m_mode=="FT4") { QString messagePriority=ui->decodedTextBrowser->CQPriority(); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 630935ac8..8170de842 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -419,7 +419,6 @@ private: float m_t0Pick; float m_t1Pick; float m_fCPUmskrtd; - float m_fSpread; qint32 m_waterfallAvg; qint32 m_ntx; From 09996d4d64663691a1071a674fc5f5a9252695c9 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 20 Jul 2020 19:33:46 +0100 Subject: [PATCH 199/239] Leave decodes titles intact when changing settings in FST240* modes --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 31b85eb05..77f944309 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1796,7 +1796,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog m_config.transceiver_online (); if(!m_bFastMode) setXIT (ui->TxFreqSpinBox->value ()); - if(m_config.single_decode() or m_mode=="JT4") { + if ((m_config.single_decode () && !m_mode.startsWith ("FST240")) || m_mode=="JT4") { ui->label_6->setText(tr ("Single-Period Decodes")); ui->label_7->setText(tr ("Average Decodes")); } From 7d07423a503da5de7df3cb6f4d2dce8cf47123e4 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 20 Jul 2020 21:24:45 +0100 Subject: [PATCH 200/239] Repair own call hash decoding in received messages --- lib/fst240_decode.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 223dc9f36..63570657e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -539,11 +539,11 @@ contains endif if(iqorw.eq.1) then write(c77,'(77i1)') mod(message101(1:77)+rvec,2) - call unpack77(c77,0,msg,unpk77_success) + call unpack77(c77,1,msg,unpk77_success) else write(c77,'(50i1)') message74(1:50) c77(51:77)='000000000000000000000110000' - call unpack77(c77,0,msg,unpk77_success) + call unpack77(c77,1,msg,unpk77_success) endif if(unpk77_success) then idupe=0 From a773a7ad1f97be298781d6909661c24a997fb504 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 20 Jul 2020 16:09:22 -0500 Subject: [PATCH 201/239] Center the DT search window properly. Write fort.21 when plotspec exists. --- lib/fst240_decode.f90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 223dc9f36..a7ff2c7fb 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -87,7 +87,7 @@ contains dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall - fMHz=1.0 + fMHz=1.0e9 if(first) then mcq=2*mod(mcq+rvec(1:29),2)-1 @@ -325,7 +325,7 @@ contains is0=1.5*nspsec ishw=1.5*nspsec else ! search plus or minus 1.5 s centered on emedelay - is0=nint(emedelay*nspsec) + is0=nint((emedelay+1.0)*nspsec) ishw=1.5*nspsec endif @@ -581,9 +581,11 @@ contains nsnr=nint(xsnr) qual=0. fsig=fc_synced - 1.5*hmod*baud -! write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & -! nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg -! flush(21) + if(ex) then + write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & + nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg + flush(21) + endif call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & iaptype,qual,ntrperiod,lwspr,fmid,w50) goto 2002 From 2da65408a86c2fbc8ba508b654dedc90105cc309 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Mon, 20 Jul 2020 23:53:29 +0100 Subject: [PATCH 202/239] Fix filename case issue --- lib/{c_interface_module.f90 => C_interface_module.f90} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{c_interface_module.f90 => C_interface_module.f90} (100%) diff --git a/lib/c_interface_module.f90 b/lib/C_interface_module.f90 similarity index 100% rename from lib/c_interface_module.f90 rename to lib/C_interface_module.f90 From 0f6d0542767e1fcaae9ee31e476d12104ca1302b Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 21 Jul 2020 00:29:22 +0100 Subject: [PATCH 203/239] Narrow decode prints in the Band Activity window --- widgets/displaytext.cpp | 56 +++++++++++++++++++++++++---------------- widgets/displaytext.h | 3 ++- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 75807c959..6d807c353 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -241,10 +241,9 @@ void DisplayText::new_period () QString DisplayText::appendWorkedB4 (QString message, QString call, QString const& grid, QColor * bg, QColor * fg, LogBook const& logBook, - QString const& currentBand, QString const& currentMode) + QString const& currentBand, QString const& currentMode, + QString extra) { - // allow for seconds - int padding {message.indexOf (" ") > 4 ? 2 : 0}; QString countryName; bool callB4; bool callB4onBand; @@ -278,7 +277,6 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons } message = message.trimmed (); - QString appendage; highlight_types types; // no shortcuts here as some types may be disabled @@ -329,20 +327,20 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons { case Highlight::Continent: case Highlight::ContinentBand: - appendage = AD1CCty::continent (looked_up.continent); + extra += AD1CCty::continent (looked_up.continent); break; case Highlight::CQZone: case Highlight::CQZoneBand: - appendage = QString {"CQ Zone %1"}.arg (looked_up.CQ_zone); + extra += QString {"CQ Zone %1"}.arg (looked_up.CQ_zone); break; case Highlight::ITUZone: case Highlight::ITUZoneBand: - appendage = QString {"ITU Zone %1"}.arg (looked_up.ITU_zone); + extra += QString {"ITU Zone %1"}.arg (looked_up.ITU_zone); break; default: if (m_bPrincipalPrefix) { - appendage = looked_up.primary_prefix; + extra += looked_up.primary_prefix; } else { @@ -368,19 +366,30 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons countryName.replace ("European", "EU"); countryName.replace ("African", "AF"); - appendage += countryName; + extra += countryName; } } m_CQPriority=DecodeHighlightingModel::highlight_name(top_highlight); - // use a nbsp to save the start of appended text so we can find - // it again later, align appended data at a fixed column if - // there is space otherwise let it float to the right - int space_count {40 + padding - message.size ()}; - if (space_count > 0) { - message += QString {space_count, QChar {' '}}; - } - message += QChar::Nbsp + appendage; + return leftJustifyAppendage (message, extra); +} + +QString DisplayText::leftJustifyAppendage (QString message, QString const& appendage) const +{ + if (appendage.size ()) + { + // allow for seconds + int padding {message.indexOf (" ") > 4 ? 2 : 0}; + + // use a nbsp to save the start of appended text so we can find + // it again later, align appended data at a fixed column if + // there is space otherwise let it float to the right + int space_count {40 + padding - message.size ()}; + if (space_count > 0) { + message += QString {space_count, QChar {' '}}; + } + message += QChar::Nbsp + appendage; + } return message; } @@ -421,11 +430,11 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con decodedText.deCallAndGrid (/*out*/ dxCall, dxGrid); QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; if(!dxGrid.contains(grid_regexp)) dxGrid=""; - message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info + message = message.left (message.indexOf (QChar::Nbsp)).trimmed (); // strip appended info + QString extra; if (haveFSpread) { - message += QString {37 - message.size (), QChar {' '}}; - message += QChar::Nbsp + QString {"%1"}.arg (fSpread, 5, 'f', fSpread < 0.95 ? 3 : 2); + extra = QString {"%1"}.arg (fSpread, 5, 'f', fSpread < 0.95 ? 3 : 2) + QChar {' '}; } m_CQPriority=""; if (CQcall) @@ -440,10 +449,11 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con currentMode = decodedText.isJT65 () ? "JT65" : "JT9"; } message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg - , logBook, currentBand, currentMode); + , logBook, currentBand, currentMode, extra); } else { + message = leftJustifyAppendage (message, extra); highlight_types types {Highlight::CQ}; if (m_config && m_config->lotw_users ().user (decodedText.CQersCall())) { @@ -452,6 +462,10 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con set_colours (m_config, &bg, &fg, types); } } + else + { + message = leftJustifyAppendage (message, extra); + } appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall); } diff --git a/widgets/displaytext.h b/widgets/displaytext.h index fbbfa5656..3b577e619 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -47,6 +47,7 @@ public: Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_period_only); private: + QString leftJustifyAppendage (QString message, QString const& appendage) const; void mouseDoubleClickEvent (QMouseEvent *) override; void extend_vertical_scrollbar (int min, int max); @@ -57,7 +58,7 @@ private: QString appendWorkedB4(QString message, QString callsign , QString const& grid, QColor * bg, QColor * fg , LogBook const& logBook, QString const& currentBand - , QString const& currentMode); + , QString const& currentMode, QString extra); QFont char_font_; QAction * erase_action_; QHash> highlighted_calls_; From 5111dcdfa87ee25822e54cf97c30744e1247577d Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 21 Jul 2020 14:57:44 +0100 Subject: [PATCH 204/239] Include sub-mode in .WAV file meta-data for FST240 modes --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 77f944309..600d75217 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1589,7 +1589,7 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int auto source = QString {"%1, %2"}.arg (my_callsign).arg (my_grid); auto comment = QString {"Mode=%1%2, Freq=%3%4"} .arg (mode) - .arg (QString {mode.contains ('J') && !mode.contains ('+') + .arg (QString {(mode.contains ('J') && !mode.contains ('+')) || mode.startsWith ("FST240") ? QString {", Sub Mode="} + QChar {'A' + sub_mode} : QString {}}) .arg (Radio::frequency_MHz_string (frequency)) From bb9e1b1b90a0e7ce2936b647f23bded35f5e855a Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 21 Jul 2020 12:37:26 -0500 Subject: [PATCH 205/239] Remove 'Also FST240W' capability from fst240_decode. --- lib/fst240_decode.f90 | 739 +++++++++++++++++++++--------------------- 1 file changed, 361 insertions(+), 378 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f415822da..73e33f08e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -81,13 +81,15 @@ contains save first,apbits,nappasses,naptypes,mycall0,hiscall0 ! call blanker(iwave,ntrperiod*12000,0.0,0.2) - + this%callback => callback dxcall13=hiscall ! initialize for use in packjt77 mycall13=mycall - fMHz=1.0e9 + fMHz=1.0 + + if(iwspr.ne.0.and.iwspr.ne.1) return if(first) then mcq=2*mod(mcq+rvec(1:29),2)-1 @@ -123,7 +125,7 @@ contains hiscall0='' first=.false. endif - + l1=index(mycall,char(0)) if(l1.ne.0) mycall(l1:)=" " l1=index(hiscall,char(0)) @@ -228,7 +230,7 @@ contains allocate( c_bigfft(0:nfft1/2) ) allocate( c2(0:nfft2-1) ) allocate( cframe(0:160*nss-1) ) - + if(ndepth.eq.3) then nblock=4 jittermax=2 @@ -250,16 +252,6 @@ contains c_bigfft(i)=cmplx(float(iwave(2*i+1)),float(iwave(2*i+2))) enddo call four2a(c_bigfft,nfft1,1,-1,0) - if(iwspr.eq.0) then - itype1=1 - itype2=1 - elseif( iwspr.eq.1 ) then - itype1=2 - itype2=2 - elseif( iwspr.eq.2 ) then - itype1=1 - itype2=2 - endif if(hmod.eq.1) then if(fMHz.lt.2.0) then @@ -275,325 +267,316 @@ contains if(hmod.eq.8) nsyncoh=-4 endif - do iqorw=itype1,itype2 ! iqorw=1 for QSO mode and iqorw=2 for wspr-type messages - if( iwspr.lt.2 ) then - if( single_decode ) then - fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) - fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) - else - fa=max(100,nfa) - fb=min(4800,nfb) - endif - elseif( iwspr.eq.2 .and. iqorw.eq.1 ) then - fa=max(100,nfa) - fb=nfsplit - elseif( iwspr.eq.2 .and. iqorw.eq.2 ) then - fa=nfsplit - fb=min(4800,nfb) - endif + if( single_decode ) then + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) + else + fa=max(100,nfa) + fb=min(4800,nfb) + endif - if(hmod.eq.1) then - if(ntrperiod.eq.15) minsync=1.15 - if(ntrperiod.gt.15) minsync=1.20 - elseif(hmod.gt.1) then - minsync=1.2 - endif + if(hmod.eq.1) then + if(ntrperiod.eq.15) minsync=1.15 + if(ntrperiod.gt.15) minsync=1.20 + elseif(hmod.gt.1) then + minsync=1.2 + endif ! Get first approximation of candidate frequencies - call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - minsync,ncand,candidates,base) + call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + minsync,ncand,candidates,base) - ndecodes=0 - decodes=' ' + ndecodes=0 + decodes=' ' - isbest=0 - fc2=0. - do icand=1,ncand - fc0=candidates(icand,1) - detmet=candidates(icand,2) + isbest=0 + fc2=0. + do icand=1,ncand + fc0=candidates(icand,1) + detmet=candidates(icand,2) ! Downconvert and downsample a slice of the spectrum centered on the ! rough estimate of the candidates frequency. ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown - call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) + call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) - call timer('sync240 ',0) - fc1=0.0 - if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s - is0=1.5*nspsec - ishw=1.5*nspsec - else ! search plus or minus 1.5 s centered on emedelay - is0=nint((emedelay+1.0)*nspsec) - ishw=1.5*nspsec - endif - - smax=-1.e30 - do if=-12,12 - fc=fc1 + 0.1*baud*if - do istart=max(1,is0-ishw),is0+ishw,4*hmod - call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + call timer('sync240 ',0) + fc1=0.0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint((emedelay+1.0)*nspsec) + ishw=1.5*nspsec + endif + + smax=-1.e30 + do if=-12,12 + fc=fc1 + 0.1*baud*if + do istart=max(1,is0-ishw),is0+ishw,4*hmod + call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & ntrperiod,fs2,sync) - if(sync.gt.smax) then - fc2=fc - isbest=istart - smax=sync - endif - enddo + if(sync.gt.smax) then + fc2=fc + isbest=istart + smax=sync + endif enddo - - fc1=fc2 - is0=isbest - ishw=4*hmod - isst=1*hmod - - smax=0.0 - do if=-7,7 - fc=fc1 + 0.02*baud*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & - ntrperiod,fs2,sync) - if(sync.gt.smax) then - fc2=fc - isbest=istart - smax=sync - endif - enddo - enddo - - call timer('sync240 ',1) - - fc_synced = fc0 + fc2 - dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 - candidates(icand,3)=fc_synced - candidates(icand,4)=isbest enddo + fc1=fc2 + is0=isbest + ishw=4*hmod + isst=1*hmod + + smax=0.0 + do if=-7,7 + fc=fc1 + 0.02*baud*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + ntrperiod,fs2,sync) + if(sync.gt.smax) then + fc2=fc + isbest=istart + smax=sync + endif + enddo + enddo + + call timer('sync240 ',1) + + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + candidates(icand,3)=fc_synced + candidates(icand,4)=isbest + enddo + ! remove duplicate candidates - do icand=1,ncand - fc=candidates(icand,3) - isbest=nint(candidates(icand,4)) - do ic2=1,ncand - fc2=candidates(ic2,3) - isbest2=nint(candidates(ic2,4)) - if(ic2.ne.icand .and. fc2.gt.0.0) then - if(abs(fc2-fc).lt.0.10*baud) then ! same frequency - if(abs(isbest2-isbest).le.2) then - candidates(ic2,3)=-1 - endif + do icand=1,ncand + fc=candidates(icand,3) + isbest=nint(candidates(icand,4)) + do ic2=1,ncand + fc2=candidates(ic2,3) + isbest2=nint(candidates(ic2,4)) + if(ic2.ne.icand .and. fc2.gt.0.0) then + if(abs(fc2-fc).lt.0.10*baud) then ! same frequency + if(abs(isbest2-isbest).le.2) then + candidates(ic2,3)=-1 endif endif - enddo - enddo - - ic=0 - do icand=1,ncand - if(candidates(icand,3).gt.0) then - ic=ic+1 - candidates(ic,:)=candidates(icand,:) endif enddo - ncand=ic - xsnr=0. + enddo - do icand=1,ncand - sync=candidates(icand,2) - fc_synced=candidates(icand,3) - isbest=nint(candidates(icand,4)) - xdt=(isbest-nspsec)/fs2 - if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 - call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) - do ijitter=0,jittermax - if(ijitter.eq.0) ioffset=0 - if(ijitter.eq.1) ioffset=1 - if(ijitter.eq.2) ioffset=-1 - is0=isbest+ioffset - if(is0.lt.0) cycle - cframe=c2(is0:is0+160*nss-1) - bitmetrics=0 - if(hmod.eq.1) then - call get_fst240_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) - else - call get_fst240_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) - endif - if(badsync) cycle + ic=0 + do icand=1,ncand + if(candidates(icand,3).gt.0) then + ic=ic+1 + candidates(ic,:)=candidates(icand,:) + endif + enddo + ncand=ic + xsnr=0. - hbits=0 - where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - nsync_qual=ns1+ns2+ns3+ns4+ns5 + do icand=1,ncand + sync=candidates(icand,2) + fc_synced=candidates(icand,3) + isbest=nint(candidates(icand,4)) + xdt=(isbest-nspsec)/fs2 + if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 + call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) + do ijitter=0,jittermax + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+160*nss-1) + bitmetrics=0 + if(hmod.eq.1) then + call get_fst240_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) + else + call get_fst240_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + endif + if(badsync) cycle + + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5 ! if(nsync_qual.lt. 46) cycle !### Value ?? ### - scalefac=2.83 - llra( 1: 60)=bitmetrics( 17: 76, 1) - llra( 61:120)=bitmetrics( 93:152, 1) - llra(121:180)=bitmetrics(169:228, 1) - llra(181:240)=bitmetrics(245:304, 1) - llra=scalefac*llra - llrb( 1: 60)=bitmetrics( 17: 76, 2) - llrb( 61:120)=bitmetrics( 93:152, 2) - llrb(121:180)=bitmetrics(169:228, 2) - llrb(181:240)=bitmetrics(245:304, 2) - llrb=scalefac*llrb - llrc( 1: 60)=bitmetrics( 17: 76, 3) - llrc( 61:120)=bitmetrics( 93:152, 3) - llrc(121:180)=bitmetrics(169:228, 3) - llrc(181:240)=bitmetrics(245:304, 3) - llrc=scalefac*llrc - llrd( 1: 60)=bitmetrics( 17: 76, 4) - llrd( 61:120)=bitmetrics( 93:152, 4) - llrd(121:180)=bitmetrics(169:228, 4) - llrd(181:240)=bitmetrics(245:304, 4) - llrd=scalefac*llrd + scalefac=2.83 + llra( 1: 60)=bitmetrics( 17: 76, 1) + llra( 61:120)=bitmetrics( 93:152, 1) + llra(121:180)=bitmetrics(169:228, 1) + llra(181:240)=bitmetrics(245:304, 1) + llra=scalefac*llra + llrb( 1: 60)=bitmetrics( 17: 76, 2) + llrb( 61:120)=bitmetrics( 93:152, 2) + llrb(121:180)=bitmetrics(169:228, 2) + llrb(181:240)=bitmetrics(245:304, 2) + llrb=scalefac*llrb + llrc( 1: 60)=bitmetrics( 17: 76, 3) + llrc( 61:120)=bitmetrics( 93:152, 3) + llrc(121:180)=bitmetrics(169:228, 3) + llrc(181:240)=bitmetrics(245:304, 3) + llrc=scalefac*llrc + llrd( 1: 60)=bitmetrics( 17: 76, 4) + llrd( 61:120)=bitmetrics( 93:152, 4) + llrd(121:180)=bitmetrics(169:228, 4) + llrd(181:240)=bitmetrics(245:304, 4) + llrd=scalefac*llrd - apmag=maxval(abs(llra))*1.1 - ntmax=nblock+nappasses(nQSOProgress) - if(lapcqonly) ntmax=nblock+1 - if(ndepth.eq.1) ntmax=nblock - apmask=0 + apmag=maxval(abs(llra))*1.1 + ntmax=nblock+nappasses(nQSOProgress) + if(lapcqonly) ntmax=nblock+1 + if(ndepth.eq.1) ntmax=nblock + apmask=0 - if(iqorw.eq.2) then ! 50-bit msgs, no ap decoding - nblock=4 - ntmax=nblock + if(iwspr.eq.1) then ! 50-bit msgs, no ap decoding + nblock=4 + ntmax=nblock + endif + + do itry=1,ntmax + if(itry.eq.1) llr=llra + if(itry.eq.2.and.itry.le.nblock) llr=llrb + if(itry.eq.3.and.itry.le.nblock) llr=llrc + if(itry.eq.4.and.itry.le.nblock) llr=llrd + if(itry.le.nblock) then + apmask=0 + iaptype=0 endif - do itry=1,ntmax - if(itry.eq.1) llr=llra - if(itry.eq.2.and.itry.le.nblock) llr=llrb - if(itry.eq.3.and.itry.le.nblock) llr=llrc - if(itry.eq.4.and.itry.le.nblock) llr=llrd - if(itry.le.nblock) then + if(itry.gt.nblock) then + llr=llra + if(nblock.gt.1) then + if(hmod.eq.1) llr=llrd + if(hmod.eq.2) llr=llrb + if(hmod.eq.4) llr=llrc + if(hmod.eq.8) llr=llrd + endif + iaptype=naptypes(nQSOProgress,itry-nblock) + if(lapcqonly) iaptype=1 + if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall + if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall + if(iaptype.eq.1) then ! CQ apmask=0 - iaptype=0 + apmask(1:29)=1 + llr(1:29)=apmag*mcq(1:29) endif - if(itry.gt.nblock) then - llr=llra - if(nblock.gt.1) then - if(hmod.eq.1) llr=llrd - if(hmod.eq.2) llr=llrb - if(hmod.eq.4) llr=llrc - if(hmod.eq.8) llr=llrd - endif - iaptype=naptypes(nQSOProgress,itry-nblock) - if(lapcqonly) iaptype=1 - if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall - if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - if(iaptype.eq.1) then ! CQ - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*mcq(1:29) - endif - - if(iaptype.eq.2) then ! MyCall ??? ??? - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*apbits(1:29) - endif - - if(iaptype.eq.3) then ! MyCall DxCall ??? - apmask=0 - apmask(1:58)=1 - llr(1:58)=apmag*apbits(1:58) - endif - - if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then - apmask=0 - apmask(1:77)=1 - llr(1:58)=apmag*apbits(1:58) - if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) - if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) - if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) - endif + if(iaptype.eq.2) then ! MyCall ??? ??? + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*apbits(1:29) endif - dmin=0.0 - nharderrors=-1 - unpk77_success=.false. - if(iqorw.eq.1) then - maxosd=2 - Keff=91 - norder=3 - call timer('d240_101',0) - call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & - cw,ntype,nharderrors,dmin) - call timer('d240_101',1) - elseif(iqorw.eq.2) then - maxosd=2 - call timer('d240_74 ',0) - Keff=64 - norder=4 - call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & - ntype,nharderrors,dmin) - call timer('d240_74 ',1) + if(iaptype.eq.3) then ! MyCall DxCall ??? + apmask=0 + apmask(1:58)=1 + llr(1:58)=apmag*apbits(1:58) endif - if(nharderrors .ge.0) then - if(count(cw.eq.1).eq.0) then - nharderrors=-nharderrors - cycle - endif - if(iqorw.eq.1) then - write(c77,'(77i1)') mod(message101(1:77)+rvec,2) - call unpack77(c77,1,msg,unpk77_success) + if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then + apmask=0 + apmask(1:77)=1 + llr(1:58)=apmag*apbits(1:58) + if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) + if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) + if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) + endif + endif + + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iwspr.eq.0) then + maxosd=2 + Keff=91 + norder=3 + call timer('d240_101',0) + call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & + cw,ntype,nharderrors,dmin) + call timer('d240_101',1) + elseif(iwspr.eq.1) then + maxosd=2 + call timer('d240_74 ',0) + Keff=64 + norder=4 + call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & + ntype,nharderrors,dmin) + call timer('d240_74 ',1) + endif + + if(nharderrors .ge.0) then + if(count(cw.eq.1).eq.0) then + nharderrors=-nharderrors + cycle + endif + if(iwspr.eq.0) then + write(c77,'(77i1)') mod(message101(1:77)+rvec,2) + call unpack77(c77,1,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,1,msg,unpk77_success) + endif + if(unpk77_success) then + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.msg) idupe=1 + enddo + if(idupe.eq.1) goto 2002 + ndecodes=ndecodes+1 + decodes(ndecodes)=msg + + if(iwspr.eq.0) then + call get_fst240_tones_from_bits(message101,itone,0) else - write(c77,'(50i1)') message74(1:50) - c77(51:77)='000000000000000000000110000' - call unpack77(c77,1,msg,unpk77_success) + call get_fst240_tones_from_bits(message74,itone,1) endif - if(unpk77_success) then - idupe=0 - do i=1,ndecodes - if(decodes(i).eq.msg) idupe=1 - enddo - if(idupe.eq.1) goto 2002 - ndecodes=ndecodes+1 - decodes(ndecodes)=msg - - if(iqorw.eq.1) then - call get_fst240_tones_from_bits(message101,itone,0) - else - call get_fst240_tones_from_bits(message74,itone,1) - endif - inquire(file='plotspec',exist=ex) - fmid=-999.0 - if(ex) then - call write_ref(itone,iwave,nsps,nmax,ndown,hmod, & - isbest,fc_synced,fmid,w50) - endif - xsig=0 - do i=1,NN - xsig=xsig+s4(itone(i),i)**2 - enddo - arg=400.0*(xsig/base)-1.0 - if(arg.gt.0.0) then - xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) - else - xsnr=-99.9 - endif - else - cycle - endif - nsnr=nint(xsnr) - qual=0. - fsig=fc_synced - 1.5*hmod*baud + inquire(file='plotspec',exist=ex) + fmid=-999.0 if(ex) then - write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37)') & - nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,xdt,fsig,msg - flush(21) + call write_ref(itone,iwave,nsps,nmax,ndown,hmod, & + isbest,fc_synced,fmid,w50) endif - call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual,ntrperiod,lwspr,fmid,w50) - goto 2002 + xsig=0 + do i=1,NN + xsig=xsig+s4(itone(i),i)**2 + enddo + arg=400.0*(xsig/base)-1.0 + if(arg.gt.0.0) then + xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) + else + xsnr=-99.9 + endif + else + cycle endif - enddo ! metrics - enddo ! istart jitter -2002 enddo !candidate list - enddo ! iqorw + nsnr=nint(xsnr) + qual=0. + fsig=fc_synced - 1.5*hmod*baud + if(ex) then + write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37,f5.1)') & + nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual, & + nharderrors,dmin,sync,xsnr,xdt,fsig,msg,w50 + flush(21) + endif + call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & + iaptype,qual,ntrperiod,lwspr,fmid,w50) + goto 2002 + endif + enddo ! metrics + enddo ! istart jitter +2002 enddo !candidate list return end subroutine decode @@ -829,97 +812,97 @@ contains ! On "plotspec" special request, compute Doppler spread for a decoded signal - include 'fst240/fst240_params.f90' - complex, allocatable :: cwave(:) !Reconstructed complex signal - complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper - real,allocatable :: ss(:) !Computed power spectrum of g(t) - integer itone(160) !Tones for this message - integer*2 iwave(nmax) !Raw Rx data - integer hmod !Modulation index - data ncall/0/ - save ncall + include 'fst240/fst240_params.f90' + complex, allocatable :: cwave(:) !Reconstructed complex signal + complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper + real,allocatable :: ss(:) !Computed power spectrum of g(t) + integer itone(160) !Tones for this message + integer*2 iwave(nmax) !Raw Rx data + integer hmod !Modulation index + data ncall/0/ + save ncall - ncall=ncall+1 - nfft=2*nmax - nwave=max(nmax,(NN+2)*nsps) - allocate(cwave(0:nwave-1)) - allocate(g(0:nfft-1)) - wave=0 - fsample=12000.0 - call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave) - cwave=cshift(cwave,-i0*ndown) - fac=1.0/32768 - g(0:nmax-1)=fac*float(iwave)*conjg(cwave(:nmax-1)) - g(nmax:)=0. - call four2a(g,nfft,1,-1,1) !Forward c2c FFT + ncall=ncall+1 + nfft=2*nmax + nwave=max(nmax,(NN+2)*nsps) + allocate(cwave(0:nwave-1)) + allocate(g(0:nfft-1)) + wave=0 + fsample=12000.0 + call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave) + cwave=cshift(cwave,-i0*ndown) + fac=1.0/32768 + g(0:nmax-1)=fac*float(iwave)*conjg(cwave(:nmax-1)) + g(nmax:)=0. + call four2a(g,nfft,1,-1,1) !Forward c2c FFT - df=12000.0/nfft - ia=1.0/df - smax=0. - do i=-ia,ia !Find smax in +/- 1 Hz around 0. - j=i - if(j.lt.0) j=i+nfft - s=real(g(j))**2 + aimag(g(j))**2 - smax=max(s,smax) - enddo - - ia=10.1/df - allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz - sum1=0. - sum2=0. - nns=0 - do i=-ia,ia - j=i - if(j.lt.0) j=i+nfft - ss(i)=(real(g(j))**2 + aimag(g(j))**2)/smax - f=i*df - if(f.ge.-4.0 .and. f.le.-2.0) then - sum1=sum1 + ss(i) !Power between -2 and -4 Hz - nns=nns+1 - else if(f.ge.2.0 .and. f.le.4.0) then - sum2=sum2 + ss(i) !Power between +2 and +4 Hz - endif - enddo - avg=min(sum1/nns,sum2/nns) !Compute avg from smaller sum + df=12000.0/nfft + ia=1.0/df + smax=0. + do i=-ia,ia !Find smax in +/- 1 Hz around 0. + j=i + if(j.lt.0) j=i+nfft + s=real(g(j))**2 + aimag(g(j))**2 + smax=max(s,smax) + enddo - sum1=0. - do i=-ia,ia - f=i*df - if(abs(f).le.1.0) sum1=sum1 + ss(i)-avg !Power in abs(f) < 1 Hz - enddo + ia=10.1/df + allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz + sum1=0. + sum2=0. + nns=0 + do i=-ia,ia + j=i + if(j.lt.0) j=i+nfft + ss(i)=(real(g(j))**2 + aimag(g(j))**2)/smax + f=i*df + if(f.ge.-4.0 .and. f.le.-2.0) then + sum1=sum1 + ss(i) !Power between -2 and -4 Hz + nns=nns+1 + else if(f.ge.2.0 .and. f.le.4.0) then + sum2=sum2 + ss(i) !Power between +2 and +4 Hz + endif + enddo + avg=min(sum1/nns,sum2/nns) !Compute avg from smaller sum - ia=nint(1.0/df) + 1 - sum2=0.0 - xi1=-999 - xi2=-999 - xi3=-999 - sum2z=0. - do i=-ia,ia !Find freq range that has 50% of signal power - sum2=sum2 + ss(i)-avg - if(sum2.ge.0.25*sum1 .and. xi1.eq.-999.0) then - xi1=i - 1 + (sum2-0.25*sum1)/(sum2-sum2z) - endif - if(sum2.ge.0.50*sum1 .and. xi2.eq.-999.0) then - xi2=i - 1 + (sum2-0.50*sum1)/(sum2-sum2z) - endif - if(sum2.ge.0.75*sum1) then - xi3=i - 1 + (sum2-0.75*sum1)/(sum2-sum2z) - exit - endif - sum2z=sum2 - enddo - xdiff=sqrt(1.0+(xi3-xi1)**2) !Keep small values from fluctuating too widely - w50=xdiff*df !Compute Doppler spread - fmid=xi2*df !Frequency midpoint of signal powere + sum1=0. + do i=-ia,ia + f=i*df + if(abs(f).le.1.0) sum1=sum1 + ss(i)-avg !Power in abs(f) < 1 Hz + enddo - do i=-ia,ia !Save the spectrum for plotting - f=i*df - y=0.99*ss(i+nint(xi2)) + ncall-1 - write(52,1010) f,y -1010 format(f12.6,f12.6) - enddo + ia=nint(1.0/df) + 1 + sum2=0.0 + xi1=-999 + xi2=-999 + xi3=-999 + sum2z=0. + do i=-ia,ia !Find freq range that has 50% of signal power + sum2=sum2 + ss(i)-avg + if(sum2.ge.0.25*sum1 .and. xi1.eq.-999.0) then + xi1=i - 1 + (sum2-0.25*sum1)/(sum2-sum2z) + endif + if(sum2.ge.0.50*sum1 .and. xi2.eq.-999.0) then + xi2=i - 1 + (sum2-0.50*sum1)/(sum2-sum2z) + endif + if(sum2.ge.0.75*sum1) then + xi3=i - 1 + (sum2-0.75*sum1)/(sum2-sum2z) + exit + endif + sum2z=sum2 + enddo + xdiff=sqrt(1.0+(xi3-xi1)**2) !Keep small values from fluctuating too widely + w50=xdiff*df !Compute Doppler spread + fmid=xi2*df !Frequency midpoint of signal powere - return + do i=-ia,ia !Save the spectrum for plotting + f=i*df + y=0.99*ss(i+nint(xi2)) + ncall-1 + write(52,1010) f,y +1010 format(f12.6,f12.6) + enddo + + return end subroutine write_ref end module fst240_decode From 231b518a2250ca1a5073f9b908932c7eda96929e Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 21 Jul 2020 12:42:50 -0500 Subject: [PATCH 206/239] Fix print format for w50 in fort.21 --- lib/fst240_decode.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 73e33f08e..779c3da73 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -565,7 +565,7 @@ contains qual=0. fsig=fc_synced - 1.5*hmod*baud if(ex) then - write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37,f5.1)') & + write(21,'(i6.6,8i6,f7.1,f10.2,f7.1,1x,f7.2,1x,f7.1,1x,a37,f5.3)') & nutc,icand,itry,nsyncoh,iaptype,ijitter,ntype,nsync_qual, & nharderrors,dmin,sync,xsnr,xdt,fsig,msg,w50 flush(21) From 52984a507a5052e65a590356f0acabef77774966 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 21 Jul 2020 14:11:11 -0400 Subject: [PATCH 207/239] Move the WSPR frequency range indicator (green line) up 3 pixels. --- widgets/plotter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index f5cf5c463..56ed25daf 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -480,7 +480,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_mode=="WSPR") { x1=XfromFreq(1400); x2=XfromFreq(1600); - painter0.drawLine(x1,29,x2,29); + painter0.drawLine(x1,26,x2,26); } if(m_mode=="FST240W") { From 05a1b3bae833aed28dc97fc6f30bb578c6b1e14e Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 21 Jul 2020 14:18:55 -0400 Subject: [PATCH 208/239] Remove "Also FST240W" from the Decode menu and elswhere in the GUI. --- widgets/mainwindow.cpp | 8 -------- widgets/mainwindow.h | 1 - widgets/mainwindow.ui | 3 +-- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 600d75217..0d36b9a99 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -951,7 +951,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->actionInclude_averaging->setChecked(m_ndepth&16); ui->actionInclude_correlation->setChecked(m_ndepth&32); ui->actionEnable_AP_DXcall->setChecked(m_ndepth&64); - ui->actionAlso_FST240W->setChecked(m_ndepth&128); m_UTCdisk=-1; m_fCPUmskrtd=0.0; @@ -2933,7 +2932,6 @@ void MainWindow::decode() //decode() if (!ui->actionInclude_averaging->isVisible ()) depth &= ~16; if (!ui->actionInclude_correlation->isVisible ()) depth &= ~32; if (!ui->actionEnable_AP_DXcall->isVisible ()) depth &= ~64; - if (!ui->actionAlso_FST240W->isVisible ()) depth &= ~128; dec_data.params.ndepth=depth; dec_data.params.n2pass=1; if(m_config.twoPass()) dec_data.params.n2pass=2; @@ -6493,7 +6491,6 @@ void MainWindow::switch_mode (Mode mode) ui->label_6->setVisible(false); ui->label_7->setVisible(false); } - ui->actionAlso_FST240W->setVisible(m_mode=="FST240"); } void MainWindow::WSPR_config(bool b) @@ -6592,11 +6589,6 @@ void MainWindow::on_actionEnable_AP_DXcall_toggled (bool checked) m_ndepth ^= (-checked ^ m_ndepth) & 0x00000040; } -void MainWindow::on_actionAlso_FST240W_toggled (bool checked) -{ - m_ndepth ^= (-checked ^ m_ndepth) & 0x00000080; -} - void MainWindow::on_actionErase_ALL_TXT_triggered() //Erase ALL.TXT { int ret = MessageBox::query_message (this, tr ("Confirm Erase"), diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 8170de842..687020a9c 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -263,7 +263,6 @@ private slots: void on_fox_log_action_triggered (); void on_actionColors_triggered(); void on_actionInclude_averaging_toggled (bool); - void on_actionAlso_FST240W_toggled (bool); void on_actionInclude_correlation_toggled (bool); void on_actionEnable_AP_DXcall_toggled (bool); void VHF_features_enabled(bool b); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index d43aa62f7..823ece909 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2931,7 +2931,7 @@ Yellow when too low 0 0 805 - 21 + 22 @@ -2982,7 +2982,6 @@ Yellow when too low - From 52643b01e2183fd7c6f415af2cea1cd1078839f5 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 21 Jul 2020 14:56:20 -0400 Subject: [PATCH 209/239] Correct the "time to decode" and the "Tune" frequency for FST240 modes. --- widgets/mainwindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 0d36b9a99..615fb1dfa 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1350,7 +1350,7 @@ void MainWindow::fixStop() if(m_TRperiod==120) i=3; if(m_TRperiod==300) i=4; if(m_TRperiod==900) i=5; - if(m_TRperiod==1800) i=5; + if(m_TRperiod==1800) i=6; if(m_config.decode_at_52s()) { m_hsymStop=stop_EME[i]; } else { @@ -4104,6 +4104,7 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { +// qDebug() << "AAA" << nsec; m_currentBand=m_config.bands()->find(m_freqNominal); if( SpecOp::HOUND == m_config.special_op_id() ) { qint32 tHound=QDateTime::currentMSecsSinceEpoch()/1000 - m_tAutoOn; @@ -7200,7 +7201,8 @@ void MainWindow::transmit (double snr) if(m_TRperiod==1800) nsps=134400; int hmod=int(pow(2.0,double(m_nSubMode))); double dfreq=hmod*12000.0/nsps; - double f0=ui->WSPRfreqSpinBox->value() - m_XIT + 1.5*dfreq; + double f0=ui->WSPRfreqSpinBox->value() - m_XIT; + if(!m_tune) f0 += + 1.5*dfreq; Q_EMIT sendMessage (m_mode, NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); From ffd2ad4dc01031176a49234bd0b66b754810f2d1 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 22 Jul 2020 01:05:14 +0100 Subject: [PATCH 210/239] Narrower decodes display and move AP info into extra appended info --- widgets/displaytext.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 6d807c353..2f19774de 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -434,7 +434,13 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con QString extra; if (haveFSpread) { - extra = QString {"%1"}.arg (fSpread, 5, 'f', fSpread < 0.95 ? 3 : 2) + QChar {' '}; + extra += QString {"%1"}.arg (fSpread, 5, 'f', fSpread < 0.95 ? 3 : 2) + QChar {' '}; + } + auto ap_pos = message.lastIndexOf (QRegularExpression {R"((?:\?\s)?a[0-9]$)"}); + if (ap_pos >= 0) + { + extra += message.mid (ap_pos) + QChar {' '}; + message = message.left (ap_pos).trimmed (); } m_CQPriority=""; if (CQcall) From 372651ae55d43ba2cbd36eaedca49388cdea128c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 22 Jul 2020 10:43:33 -0400 Subject: [PATCH 211/239] Add a simple execution timer for small blocks of code. --- CMakeLists.txt | 1 + lib/sec0.f90 | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 lib/sec0.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index d2ed2459b..6f524a6f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -548,6 +548,7 @@ set (wsjt_FSRCS lib/qra64a.f90 lib/refspectrum.f90 lib/savec2.f90 + lib/sec0.f90 lib/sec_midn.f90 lib/setup65.f90 lib/sh65.f90 diff --git a/lib/sec0.f90 b/lib/sec0.f90 new file mode 100644 index 000000000..1ced602ed --- /dev/null +++ b/lib/sec0.f90 @@ -0,0 +1,21 @@ +subroutine sec0(n,t) + + ! Simple execution timer. + ! call sec0(0,t) + ! ... statements to be timed ... + ! call sec0(1,t) + ! print*,'Execution time:',t + + integer*8 count0,count1,clkfreq + save count0 + + call system_clock(count1,clkfreq) + if(n.eq.0) then + count0=count1 + return + else + t=float(count1-count0)/float(clkfreq) + endif + + return +end subroutine sec0 From 51f692d8d4b71c22a73dc12024a58fc7544c94d0 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 22 Jul 2020 18:01:06 +0100 Subject: [PATCH 212/239] Avoid double Tx periods in WSPR modes when changing scheduling basis --- widgets/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 615fb1dfa..fcad7d1f3 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -5606,6 +5606,8 @@ void MainWindow::on_tx6_editingFinished() //tx6 edited void MainWindow::on_RoundRobin_currentTextChanged(QString text) { ui->sbTxPercent->setEnabled(text=="Random"); + m_WSPR_tx_next = false; // cancel any pending Tx to avoid + // undesirable consecutive Tx periods } From 77a6f8f51431fc0e0041c9ed355a3a1c1c024381 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 23 Jul 2020 10:58:10 -0400 Subject: [PATCH 213/239] Move blanking from symspec() to fst240_decode(). Do not apply RefSpec corrections to data read from disk. --- lib/blanker.f90 | 39 +++--- lib/fst240_decode.f90 | 12 +- lib/symspec.f90 | 11 +- widgets/mainwindow.cpp | 24 ++-- widgets/mainwindow.ui | 300 +++++++++++++++++++---------------------- 5 files changed, 182 insertions(+), 204 deletions(-) diff --git a/lib/blanker.f90 b/lib/blanker.f90 index a5c334e3f..6dd496f81 100644 --- a/lib/blanker.f90 +++ b/lib/blanker.f90 @@ -1,14 +1,11 @@ -subroutine blanker(iwave,nz,dwell_time,fblank,npct) +subroutine blanker(iwave,nz,ndropmax,npct,c_bigfft) integer*2 iwave(nz) + complex c_bigfft(0:nz/2) integer hist(0:32768) - real dwell_time !Blanking dwell time (s) real fblank !Fraction of points to be blanked - data ncall/0/,thresh/0.0/,fblanked/0.0/ - save ncall,thresh,fblanked - ncall=ncall+1 - ndropmax=nint(1.0 + dwell_time*12000.0) + fblank=0.01*npct hist=0 do i=1,nz n=abs(iwave(i)) @@ -19,34 +16,40 @@ subroutine blanker(iwave,nz,dwell_time,fblank,npct) n=n+hist(i) if(n.ge.nint(nz*fblank/ndropmax)) exit enddo - thresh=thresh + 0.01*(i-thresh) - if(ncall.eq.1) thresh=i - nthresh=nint(thresh) + nthresh=i ndrop=0 ndropped=0 - + + xx=0. do i=1,nz i0=iwave(i) if(ndrop.gt.0) then - iwave(i)=0 + i0=0 ndropped=ndropped+1 ndrop=ndrop-1 - cycle endif ! Start to apply blanking - if(abs(iwave(i)).gt.nthresh) then - iwave(i)=0 + if(abs(i0).gt.nthresh) then + i0=0 ndropped=ndropped+1 ndrop=ndropmax endif + +! Now copy the data into c_bigfft + if(iand(i,1).eq.1) then + xx=i0 + else + yy=i0 + j=i/2 - 1 + c_bigfft(j)=cmplx(xx,yy) + endif enddo fblanked=fblanked + 0.1*(float(ndropped)/nz - fblanked) - if(ncall.eq.1) fblanked=float(ndropped)/nz - npct=nint(100.0*fblanked) -! if(mod(ncall,4).eq.0) write(*,3001) thresh,dwell_time,fblank,fblanked,npct -!3001 format(f8.1,f8.4,f6.2,f7.3,i6) + fblanked=float(ndropped)/nz +! write(*,3001) npct,nthresh,fblanked +!3001 format(2i5,f7.3) return end subroutine blanker diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 779c3da73..9b52f285e 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -80,8 +80,6 @@ contains data first/.true./ save first,apbits,nappasses,naptypes,mycall0,hiscall0 -! call blanker(iwave,ntrperiod*12000,0.0,0.2) - this%callback => callback dxcall13=hiscall ! initialize for use in packjt77 @@ -246,12 +244,14 @@ contains norder=3 endif + ndropmax=1 + npct=nexp_decode/256 + call blanker(iwave,nfft1,ndropmax,npct,c_bigfft) + ! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. - do i=0,nfft1/2 - c_bigfft(i)=cmplx(float(iwave(2*i+1)),float(iwave(2*i+2))) - enddo - call four2a(c_bigfft,nfft1,1,-1,0) + call four2a(c_bigfft,nfft1,1,-1,0) !r2c +! call blank2(nfa,nfb,nfft1,c_bigfft,iwave) if(hmod.eq.1) then if(fMHz.lt.2.0) then diff --git a/lib/symspec.f90 b/lib/symspec.f90 index 5bd0fd902..a3bed192f 100644 --- a/lib/symspec.f90 +++ b/lib/symspec.f90 @@ -1,5 +1,5 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & - nminw,pxdb,s,df3,ihsym,npts8,pxdbmax,bblank,npct) + nminw,pxdb,s,df3,ihsym,npts8,pxdbmax,npct) ! Input: ! k pointer to the most recent new data @@ -29,7 +29,7 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & real*4 tmp(NSMAX) complex cx(0:MAXFFT3/2) integer nch(7) - logical*1 bLowSidelobes,bblank + logical*1 bLowSidelobes common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456) data k0/99999999/,nfft3z/0/ @@ -64,10 +64,9 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, & sq=0. pxmax=0.; - dwell_time=0.0001 - fblank=0.15 - if(k.gt.k0 .and. bblank) call blanker(shared_data%id2(k0+1:k), & - k-k0,dwell_time,fblank,npct) +! dwell_time=0.0001 +! if(k.gt.k0 .and. npct.gt.0) call blanker(shared_data%id2(k0+1:k), & +! k-k0,dwell_time,npct) do i=k0+1,k x1=shared_data%id2(i) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index fcad7d1f3..43b6dbabd 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -91,7 +91,7 @@ extern "C" { //----------------------------------------------------- C and Fortran routines void symspec_(struct dec_data *, int* k, double* trperiod, int* nsps, int* ingain, bool* bLowSidelobes, int* minw, float* px, float s[], float* df3, - int* nhsym, int* npts8, float *m_pxmax, bool *bblank, int* npct); + int* nhsym, int* npts8, float *m_pxmax, int* npct); void hspec_(short int d2[], int* k, int* nutc0, int* ntrperiod, int* nrxfreq, int* ntol, bool* bmsk144, bool* btrain, double const pcoeffs[], int* ingain, @@ -1131,7 +1131,7 @@ void MainWindow::writeSettings() m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ()); m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ()); m_settings->setValue("SplitterState",ui->splitter->saveState()); - m_settings->setValue("Blanker",ui->cbNB->isChecked()); + m_settings->setValue("Blanker",ui->sbNB->value()); { QList coeffs; // suitable for QSettings @@ -1232,7 +1232,7 @@ void MainWindow::readSettings() ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool()); ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool()); ui->splitter->restoreState(m_settings->value("SplitterState").toByteArray()); - ui->cbNB->setChecked(m_settings->value("Blanker",false).toBool()); + ui->sbNB->setValue(m_settings->value("Blanker",0).toInt()); { auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients" , QList {0., 0., 0., 0., 0.}).toList (); @@ -1377,8 +1377,10 @@ void MainWindow::dataSink(qint64 frames) } m_bUseRef=m_wideGraph->useRef(); - refspectrum_(&dec_data.d2[k-m_nsps/2],&m_bClearRefSpec,&m_bRefSpec, - &m_bUseRef,c_fname,len); + if(!m_diskData) { + refspectrum_(&dec_data.d2[k-m_nsps/2],&m_bClearRefSpec,&m_bRefSpec, + &m_bUseRef,c_fname,len); + } m_bClearRefSpec=false; if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9) { @@ -1393,13 +1395,10 @@ void MainWindow::dataSink(qint64 frames) if(m_bFastMode) nsps=6912; int nsmo=m_wideGraph->smoothYellow()-1; bool bLowSidelobes=m_config.lowSidelobes(); - bool bblank=ui->cbNB->isChecked() and m_mode.startsWith("FST240"); int npct=0; + if(m_mode.startsWith("FST240")) npct=ui->sbNB->value(); symspec_(&dec_data,&k,&m_TRperiod,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, - &m_df3,&m_ihsym,&m_npts8,&m_pxmax,&bblank,&npct); - QString t=" "; - if(bblank) t=QString::number(npct); - ui->labNpct->setText(t); + &m_df3,&m_ihsym,&m_npts8,&m_pxmax,&npct); if(m_mode=="WSPR" or m_mode=="FST240W") wspr_downsample_(dec_data.d2,&k); if(m_ihsym <=0) return; if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer @@ -2991,6 +2990,7 @@ void MainWindow::decode() //decode() dec_data.params.nexp_decode = static_cast (m_config.special_op_id()); if(m_config.single_decode()) dec_data.params.nexp_decode += 32; if(m_config.enable_VHF_features()) dec_data.params.nexp_decode += 64; + if(m_mode.startsWith("FST240")) dec_data.params.nexp_decode += 256*ui->sbNB->value(); ::memcpy(dec_data.params.datetime, m_dateTime.toLatin1()+" ", sizeof dec_data.params.datetime); ::memcpy(dec_data.params.mycall, (m_config.my_callsign()+" ").toLatin1(), sizeof dec_data.params.mycall); @@ -5837,9 +5837,7 @@ void MainWindow::displayWidgets(qint64 n) ui->sbSerialNumber->setVisible(b); m_lastCallsign.clear (); // ensures Tx5 is updated for new modes b=m_mode.startsWith("FST240"); - ui->labNpct->setVisible(b); - ui->labNB->setVisible(b); - ui->cbNB->setVisible(b); + ui->sbNB->setVisible(b); genStdMsgs (m_rpt, true); } diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 823ece909..cfff2fad3 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -554,7 +554,46 @@ - + + + + + 0 + 0 + + + + QLabel { + font-family: MS Shell Dlg 2; + font-size: 16pt; + background-color : black; + color : yellow; +} + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 2 + + + 0 + + + <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> + + + Qt::AlignCenter + + + 5 + + + + 0 @@ -2401,45 +2440,6 @@ list. The list can be maintained in Settings (F2). - - - - - 0 - 0 - - - - QLabel { - font-family: MS Shell Dlg 2; - font-size: 16pt; - background-color : black; - color : yellow; -} - - - QFrame::StyledPanel - - - QFrame::Sunken - - - 2 - - - 0 - - - <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> - - - Qt::AlignCenter - - - 5 - - - @@ -2447,7 +2447,7 @@ list. The list can be maintained in Settings (F2). - + @@ -2468,7 +2468,7 @@ list. The list can be maintained in Settings (F2). 0 - + @@ -2560,7 +2560,42 @@ list. The list can be maintained in Settings (F2). - + + + + + 0 + 0 + + + + true + + + Az: 251 16553 km + + + Qt::AlignCenter + + + 4 + + + + + + + Callsign of station to be worked + + + + + + Qt::AlignCenter + + + + @@ -2652,20 +2687,7 @@ list. The list can be maintained in Settings (F2). - - - - Callsign of station to be worked - - - - - - Qt::AlignCenter - - - - + Search for callsign in database @@ -2675,7 +2697,7 @@ list. The list can be maintained in Settings (F2). - + Locator of station to be worked @@ -2688,29 +2710,7 @@ list. The list can be maintained in Settings (F2). - - - - - 0 - 0 - - - - true - - - Az: 251 16553 km - - - Qt::AlignCenter - - - 4 - - - - + Add callsign and locator to database @@ -2723,6 +2723,28 @@ list. The list can be maintained in Settings (F2). + + + + <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + + Frequency entry + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + + + true + + + QComboBox::NoInsert + + + QComboBox::AdjustToMinimumContentsLength + + + @@ -2765,7 +2787,7 @@ QPushButton[state="ok"] { - + Adjust Tx audio level @@ -2793,25 +2815,37 @@ QPushButton[state="ok"] { - - + + + + + 0 + 0 + + + + + 100 + 16777215 + + - <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> - Frequency entry + Rx Signal - Select operating band or enter frequency in MHz or enter kHz increment followed by k. + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low - - true + + QFrame::Panel - - QComboBox::NoInsert - - - QComboBox::AdjustToMinimumContentsLength + + QFrame::Sunken @@ -2849,78 +2883,22 @@ QLabel[oob="true"] { - - - - - 0 - 0 - + + + + Qt::AlignCenter - - - 100 - 16777215 - + + % - - <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + NB - - Rx Signal - - - 30dB recommended when only noise present -Green when good -Red when clipping may occur -Yellow when too low - - - QFrame::Panel - - - QFrame::Sunken + + 25 - - - - - - NB - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - @@ -2931,7 +2909,7 @@ Yellow when too low 0 0 805 - 22 + 21 From 085e63e05d41fb71abd7cb32daa21ec00d94b870 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 23 Jul 2020 12:48:50 -0500 Subject: [PATCH 214/239] Rename fst240 to fst4 in Fortran routines. --- CMakeLists.txt | 40 +++---- lib/decoder.f90 | 26 ++--- lib/{fst240 => fst4}/bpdecode240_101.f90 | 0 lib/{fst240 => fst4}/decode240_101.f90 | 0 lib/{fst240 => fst4}/decode240_74.f90 | 0 lib/{fst240 => fst4}/encode240_101.f90 | 0 lib/{fst240 => fst4}/encode240_74.f90 | 0 .../fst4_params.f90} | 2 +- .../fst240sim.f90 => fst4/fst4sim.f90} | 14 +-- .../gen_fst4wave.f90} | 4 +- lib/fst4/genfst240_64.f90 | 108 ++++++++++++++++++ .../genfst240.f90 => fst4/genfst4.f90} | 8 +- lib/{fst240 => fst4}/get_crc24.f90 | 0 .../get_fst4_bitmetrics.f90} | 6 +- .../get_fst4_bitmetrics2.f90} | 6 +- .../ldpc_240_101_generator.f90 | 0 lib/{fst240 => fst4}/ldpc_240_101_parity.f90 | 0 .../ldpc_240_74_generator.f90 | 0 lib/{fst240 => fst4}/ldpc_240_74_parity.f90 | 0 lib/{fst240 => fst4}/ldpcsim240_101.f90 | 0 lib/{fst240 => fst4}/ldpcsim240_74.f90 | 0 lib/{fst240 => fst4}/osd240_101.f90 | 0 lib/{fst240 => fst4}/osd240_74.f90 | 0 lib/{fst240_decode.f90 => fst4_decode.f90} | 60 +++++----- 24 files changed, 191 insertions(+), 83 deletions(-) rename lib/{fst240 => fst4}/bpdecode240_101.f90 (100%) rename lib/{fst240 => fst4}/decode240_101.f90 (100%) rename lib/{fst240 => fst4}/decode240_74.f90 (100%) rename lib/{fst240 => fst4}/encode240_101.f90 (100%) rename lib/{fst240 => fst4}/encode240_74.f90 (100%) rename lib/{fst240/fst240_params.f90 => fst4/fst4_params.f90} (94%) rename lib/{fst240/fst240sim.f90 => fst4/fst4sim.f90} (91%) rename lib/{fst240/gen_fst240wave.f90 => fst4/gen_fst4wave.f90} (96%) create mode 100644 lib/fst4/genfst240_64.f90 rename lib/{fst240/genfst240.f90 => fst4/genfst4.f90} (94%) rename lib/{fst240 => fst4}/get_crc24.f90 (100%) rename lib/{fst240/get_fst240_bitmetrics.f90 => fst4/get_fst4_bitmetrics.f90} (95%) rename lib/{fst240/get_fst240_bitmetrics2.f90 => fst4/get_fst4_bitmetrics2.f90} (96%) rename lib/{fst240 => fst4}/ldpc_240_101_generator.f90 (100%) rename lib/{fst240 => fst4}/ldpc_240_101_parity.f90 (100%) rename lib/{fst240 => fst4}/ldpc_240_74_generator.f90 (100%) rename lib/{fst240 => fst4}/ldpc_240_74_parity.f90 (100%) rename lib/{fst240 => fst4}/ldpcsim240_101.f90 (100%) rename lib/{fst240 => fst4}/ldpcsim240_74.f90 (100%) rename lib/{fst240 => fst4}/osd240_101.f90 (100%) rename lib/{fst240 => fst4}/osd240_74.f90 (100%) rename lib/{fst240_decode.f90 => fst4_decode.f90} (94%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f524a6f5..f09a6f1df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,7 +371,7 @@ set (wsjt_FSRCS lib/jt65_mod.f90 lib/ft8_decode.f90 lib/ft4_decode.f90 - lib/fst240_decode.f90 + lib/fst4_decode.f90 lib/jt9_decode.f90 lib/options.f90 lib/packjt.f90 @@ -600,20 +600,20 @@ set (wsjt_FSRCS lib/wqencode.f90 lib/wspr_downsample.f90 lib/zplot9.f90 - lib/fst240/decode240_101.f90 - lib/fst240/decode240_74.f90 - lib/fst240/encode240_101.f90 - lib/fst240/encode240_74.f90 - lib/fst240/fst240sim.f90 - lib/fst240/gen_fst240wave.f90 - lib/fst240/genfst240.f90 - lib/fst240/get_fst240_bitmetrics.f90 - lib/fst240/get_fst240_bitmetrics2.f90 - lib/fst240/ldpcsim240_101.f90 - lib/fst240/ldpcsim240_74.f90 - lib/fst240/osd240_101.f90 - lib/fst240/osd240_74.f90 - lib/fst240/get_crc24.f90 + lib/fst4/decode240_101.f90 + lib/fst4/decode240_74.f90 + lib/fst4/encode240_101.f90 + lib/fst4/encode240_74.f90 + lib/fst4/fst4sim.f90 + lib/fst4/gen_fst4wave.f90 + lib/fst4/genfst4.f90 + lib/fst4/get_fst4_bitmetrics.f90 + lib/fst4/get_fst4_bitmetrics2.f90 + lib/fst4/ldpcsim240_101.f90 + lib/fst4/ldpcsim240_74.f90 + lib/fst4/osd240_101.f90 + lib/fst4/osd240_74.f90 + lib/fst4/get_crc24.f90 ) # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit @@ -1376,13 +1376,13 @@ target_link_libraries (ft4sim_mult wsjt_fort wsjt_cxx) add_executable (record_time_signal Audio/tools/record_time_signal.cpp) target_link_libraries (record_time_signal wsjt_cxx wsjt_qtmm wsjt_qt) -add_executable (fst240sim lib/fst240/fst240sim.f90 wsjtx.rc) -target_link_libraries (fst240sim wsjt_fort wsjt_cxx) +add_executable (fst4sim lib/fst4/fst4sim.f90 wsjtx.rc) +target_link_libraries (fst4sim wsjt_fort wsjt_cxx) -add_executable (ldpcsim240_101 lib/fst240/ldpcsim240_101.f90 wsjtx.rc) +add_executable (ldpcsim240_101 lib/fst4/ldpcsim240_101.f90 wsjtx.rc) target_link_libraries (ldpcsim240_101 wsjt_fort wsjt_cxx) -add_executable (ldpcsim240_74 lib/fst240/ldpcsim240_74.f90 wsjtx.rc) +add_executable (ldpcsim240_74 lib/fst4/ldpcsim240_74.f90 wsjtx.rc) target_link_libraries (ldpcsim240_74 wsjt_fort wsjt_cxx) endif(WSJT_BUILD_UTILS) @@ -1524,7 +1524,7 @@ install (TARGETS jt9 wsprd fmtave fcal fmeasure if(WSJT_BUILD_UTILS) install (TARGETS ft8code jt65code qra64code qra64sim jt9code jt4code - msk144code fst240sim + msk144code fst4sim RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime ) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index bb7aaaa8e..49e8681f3 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -8,7 +8,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) use jt9_decode use ft8_decode use ft4_decode - use fst240_decode + use fst4_decode include 'jt9com.f90' include 'timer_common.inc' @@ -33,9 +33,9 @@ subroutine multimode_decoder(ss,id2,params,nfsample) integer :: decoded end type counting_ft4_decoder - type, extends(fst240_decoder) :: counting_fst240_decoder + type, extends(fst4_decoder) :: counting_fst4_decoder integer :: decoded - end type counting_fst240_decoder + end type counting_fst4_decoder real ss(184,NSMAX) logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,ex @@ -53,7 +53,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) type(counting_jt9_decoder) :: my_jt9 type(counting_ft8_decoder) :: my_ft8 type(counting_ft4_decoder) :: my_ft4 - type(counting_fst240_decoder) :: my_fst240 + type(counting_fst4_decoder) :: my_fst4 !cast C character arrays to Fortran character strings datetime=transfer(params%datetime, datetime) @@ -68,7 +68,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) my_jt9%decoded = 0 my_ft8%decoded = 0 my_ft4%decoded = 0 - my_fst240%decoded = 0 + my_fst4%decoded = 0 ! For testing only: return Rx messages stored in a file as decodes inquire(file='rx_messages.txt',exist=ex) @@ -193,7 +193,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) iwspr=0 if(iand(params%ndepth,128).ne.0) iwspr=2 call timer('dec240 ',0) - call my_fst240%decode(fst240_decoded,id2,params%nutc, & + call my_fst4%decode(fst4_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%ntol,params%emedelay, & @@ -207,7 +207,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ndepth=iand(params%ndepth,3) iwspr=1 call timer('dec240 ',0) - call my_fst240%decode(fst240_decoded,id2,params%nutc, & + call my_fst4%decode(fst4_decoded,id2,params%nutc, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%ntol,params%emedelay, & @@ -335,7 +335,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ! JT65 is not yet producing info for nsynced, ndecoded. 800 ndecoded = my_jt4%decoded + my_jt65%decoded + my_jt9%decoded + & - my_ft8%decoded + my_ft4%decoded + my_fst240%decoded + my_ft8%decoded + my_ft4%decoded + my_fst4%decoded if(params%nmode.eq.8 .and. params%nzhsym.eq.41) ndec41=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.47) ndec47=ndecoded if(params%nmode.eq.8 .and. params%nzhsym.eq.50) then @@ -697,13 +697,13 @@ contains return end subroutine ft4_decoded - subroutine fst240_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & + subroutine fst4_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, & qual,ntrperiod,lwspr,fmid,w50) - use fst240_decode + use fst4_decode implicit none - class(fst240_decoder), intent(inout) :: this + class(fst4_decoder), intent(inout) :: this integer, intent(in) :: nutc real, intent(in) :: sync integer, intent(in) :: nsnr @@ -752,11 +752,11 @@ contains call flush(13) select type(this) - type is (counting_fst240_decoder) + type is (counting_fst4_decoder) this%decoded = this%decoded + 1 end select return - end subroutine fst240_decoded + end subroutine fst4_decoded end subroutine multimode_decoder diff --git a/lib/fst240/bpdecode240_101.f90 b/lib/fst4/bpdecode240_101.f90 similarity index 100% rename from lib/fst240/bpdecode240_101.f90 rename to lib/fst4/bpdecode240_101.f90 diff --git a/lib/fst240/decode240_101.f90 b/lib/fst4/decode240_101.f90 similarity index 100% rename from lib/fst240/decode240_101.f90 rename to lib/fst4/decode240_101.f90 diff --git a/lib/fst240/decode240_74.f90 b/lib/fst4/decode240_74.f90 similarity index 100% rename from lib/fst240/decode240_74.f90 rename to lib/fst4/decode240_74.f90 diff --git a/lib/fst240/encode240_101.f90 b/lib/fst4/encode240_101.f90 similarity index 100% rename from lib/fst240/encode240_101.f90 rename to lib/fst4/encode240_101.f90 diff --git a/lib/fst240/encode240_74.f90 b/lib/fst4/encode240_74.f90 similarity index 100% rename from lib/fst240/encode240_74.f90 rename to lib/fst4/encode240_74.f90 diff --git a/lib/fst240/fst240_params.f90 b/lib/fst4/fst4_params.f90 similarity index 94% rename from lib/fst240/fst240_params.f90 rename to lib/fst4/fst4_params.f90 index f6204915d..6f6878300 100644 --- a/lib/fst240/fst240_params.f90 +++ b/lib/fst4/fst4_params.f90 @@ -1,4 +1,4 @@ -! FST240 +! FST4 ! LDPC(240,101)/CRC24 code, five 8x4 sync parameter (KK=77) !Information bits (77 + CRC24) diff --git a/lib/fst240/fst240sim.f90 b/lib/fst4/fst4sim.f90 similarity index 91% rename from lib/fst240/fst240sim.f90 rename to lib/fst4/fst4sim.f90 index f687036b0..5b8f33bc3 100644 --- a/lib/fst240/fst240sim.f90 +++ b/lib/fst4/fst4sim.f90 @@ -1,10 +1,10 @@ -program fst240sim +program fst4sim ! Generate simulated signals for experimental slow FT4 mode use wavhdr use packjt77 - include 'fst240_params.f90' !Set various constants + include 'fst4_params.f90' !Set various constants type(hdr) h !Header for .wav file logical*1 wspr_hint character arg*12,fname*17 @@ -21,8 +21,8 @@ program fst240sim nargs=iargc() if(nargs.ne.10) then print*,'Need 10 arguments, got ',nargs - print*,'Usage: fst240sim "message" TRsec f0 DT h fdop del nfiles snr W' - print*,'Examples: fst240sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15 F' + print*,'Usage: fst4sim "message" TRsec f0 DT h fdop del nfiles snr W' + print*,'Examples: fst4sim "K1JT K9AN EN50" 60 1500 0.0 1 0.1 1.0 10 -15 F' print*,'W (T or F) argument is hint to encoder to use WSPR message when there is abiguity' go to 999 endif @@ -86,7 +86,7 @@ program fst240sim endif call pack77(msg37,i3,n3,c77) if(i3.eq.0.and.n3.eq.6) iwspr=1 - call genfst240(msg37,0,msgsent37,msgbits,itone,iwspr) + call genfst4(msg37,0,msgsent37,msgbits,itone,iwspr) write(*,*) write(*,'(a9,a37,a3,L2,a7,i2)') 'Message: ',msgsent37,'W:',wspr_hint,' iwspr:',iwspr write(*,1000) f00,xdt,hmod,txt,snrdb @@ -109,7 +109,7 @@ program fst240sim fsample=12000.0 icmplx=1 f0=f00+1.5*hmod*baud - call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,f0,icmplx,c0,wave) + call gen_fst4wave(itone,NN,nsps,nwave,fsample,hmod,f0,icmplx,c0,wave) k=nint((xdt+1.0)/dt) if(nsec.eq.15) k=nint((xdt+0.5)/dt) c0=cshift(c0,-k) @@ -152,4 +152,4 @@ program fst240sim 1110 format(i4,f7.2,f8.2,f7.1,2x,a17) enddo -999 end program fst240sim +999 end program fst4sim diff --git a/lib/fst240/gen_fst240wave.f90 b/lib/fst4/gen_fst4wave.f90 similarity index 96% rename from lib/fst240/gen_fst240wave.f90 rename to lib/fst4/gen_fst4wave.f90 index 49fc55ab7..ead00709b 100644 --- a/lib/fst240/gen_fst240wave.f90 +++ b/lib/fst4/gen_fst4wave.f90 @@ -1,4 +1,4 @@ -subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & +subroutine gen_fst4wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & icmplx,cwave,wave) parameter(NTAB=65536) @@ -88,4 +88,4 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, & endif return -end subroutine gen_fst240wave +end subroutine gen_fst4wave diff --git a/lib/fst4/genfst240_64.f90 b/lib/fst4/genfst240_64.f90 new file mode 100644 index 000000000..378f8a035 --- /dev/null +++ b/lib/fst4/genfst240_64.f90 @@ -0,0 +1,108 @@ +subroutine genfst240_64(msg0,ichk,msgsent,msgbits,i4tone,iwspr) + +! Input: +! - msg0 requested message to be transmitted +! - ichk if ichk=1, return only msgsent +! - msgsent message as it will be decoded +! - i4tone array of audio tone values, {0,1,2,3} +! - iwspr 0: (240,101)/crc24, 1: (240,74)/crc24 +! +! Frame structure: +! s8 d30 s8 d30 s8 d30 s8 d30 s8 + + use packjt77 + include 'fst240_params.f90' + character*37 msg0 + character*37 message !Message to be generated + character*37 msgsent !Message as it will be received + character*77 c77 + character*24 c24 + integer*4 i4tone(NN),itmp(ND) + integer*1 codeword(2*ND) + integer*1 msgbits(101),rvec(77) + integer isyncword1(8),isyncword2(8) + integer ncrc24 + integer graymap64(64) + logical unpk77_success + data isyncword1/3,1,4,0,6,5,2/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 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/ + data graymap64/ 0, 1, 3, 2, 6, 7, 5, 4,12,13,15,14,10,11, 9, 8, & + 24,25,27,26,30,31,29,28,20,21,23,22,18,19,17,16, & + 48,49,51,50,54,55,53,52,60,61,63,62,58,59,57,56, & + 40,41,43,42,46,47,45,44,36,37,39,38,34,35,33,32/ + message=msg0 + + do i=1, 37 + if(ichar(message(i:i)).eq.0) then + message(i:37)=' ' + exit + endif + enddo + do i=1,37 !Strip leading blanks + if(message(1:1).ne.' ') exit + message=message(i+1:) + enddo + + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) + call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent + msgbits=0 + iwspr=0 + if(i3.eq.0.and.n3.eq.6) then + iwspr=1 + read(c77,'(50i1)') msgbits(1:50) + call get_crc24(msgbits,74,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(51:74) + else + read(c77,'(77i1)') msgbits(1:77) + msgbits(1:77)=mod(msgbits(1:77)+rvec,2) + call get_crc24(msgbits,101,ncrc24) + write(c24,'(b24.24)') ncrc24 + read(c24,'(24i1)') msgbits(78:101) + endif + + if(ichk.eq.1) go to 999 + if(unpk77_success) go to 2 +1 msgbits=0 + itone=0 + msgsent='*** bad message *** ' + go to 999 + + entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) + +2 continue + if(iwspr.eq.0) then + call encode240_101(msgbits,codeword) + else + call encode240_74(msgbits(1:74),codeword) + endif + +! Grayscale mapping: +! bits tone + + do i=1,40 + is=codeword(2*i)+2*codeword(2*i-1) + if(is.le.1) itmp(i)=is + if(is.eq.2) itmp(i)=3 + if(is.eq.3) itmp(i)=2 + enddo + + i4tone( 1: 8)=isyncword1 + i4tone( 9: 38)=itmp( 1: 30) + i4tone( 39: 46)=isyncword2 + i4tone( 47: 76)=itmp( 31: 60) + i4tone( 77: 84)=isyncword1 + i4tone( 85:114)=itmp( 61: 90) + i4tone(115:122)=isyncword2 + i4tone(123:152)=itmp( 91:120) + i4tone(153:160)=isyncword1 + +999 return + +end subroutine genfst240_64 + +subroutine graycode(in diff --git a/lib/fst240/genfst240.f90 b/lib/fst4/genfst4.f90 similarity index 94% rename from lib/fst240/genfst240.f90 rename to lib/fst4/genfst4.f90 index 2d4a055ae..818feee43 100644 --- a/lib/fst240/genfst240.f90 +++ b/lib/fst4/genfst4.f90 @@ -1,4 +1,4 @@ -subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) +subroutine genfst4(msg0,ichk,msgsent,msgbits,i4tone,iwspr) ! Input: ! - msg0 requested message to be transmitted @@ -12,7 +12,7 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) ! s8 d30 s8 d30 s8 d30 s8 d30 s8 use packjt77 - include 'fst240_params.f90' + include 'fst4_params.f90' character*37 msg0 character*37 message !Message to be generated character*37 msgsent !Message as it will be received @@ -73,7 +73,7 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) msgsent='*** bad message *** ' go to 999 - entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) + entry get_fst4_tones_from_bits(msgbits,i4tone,iwspr) 2 continue if(iwspr.eq.0) then @@ -108,4 +108,4 @@ subroutine genfst240(msg0,ichk,msgsent,msgbits,i4tone,iwspr) 999 return -end subroutine genfst240 +end subroutine genfst4 diff --git a/lib/fst240/get_crc24.f90 b/lib/fst4/get_crc24.f90 similarity index 100% rename from lib/fst240/get_crc24.f90 rename to lib/fst4/get_crc24.f90 diff --git a/lib/fst240/get_fst240_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 similarity index 95% rename from lib/fst240/get_fst240_bitmetrics.f90 rename to lib/fst4/get_fst4_bitmetrics.f90 index e82d73c99..76a00dc2e 100644 --- a/lib/fst240/get_fst240_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -1,6 +1,6 @@ -subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) +subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) - include 'fst240_params.f90' + include 'fst4_params.f90' complex cd(0:NN*nss-1) complex cs(0:3,NN) complex csymb(nss) @@ -128,4 +128,4 @@ subroutine get_fst240_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) call normalizebmet(bitmetrics(:,4),2*NN) return -end subroutine get_fst240_bitmetrics +end subroutine get_fst4_bitmetrics diff --git a/lib/fst240/get_fst240_bitmetrics2.f90 b/lib/fst4/get_fst4_bitmetrics2.f90 similarity index 96% rename from lib/fst240/get_fst240_bitmetrics2.f90 rename to lib/fst4/get_fst4_bitmetrics2.f90 index 7b86841ba..da0a6a230 100644 --- a/lib/fst240/get_fst240_bitmetrics2.f90 +++ b/lib/fst4/get_fst4_bitmetrics2.f90 @@ -1,6 +1,6 @@ -subroutine get_fst240_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) +subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) - include 'fst240_params.f90' + include 'fst4_params.f90' complex cd(0:NN*nss-1) complex csymb(nss) complex, allocatable, save :: c1(:,:) ! ideal waveforms, 4 tones @@ -128,4 +128,4 @@ subroutine get_fst240_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) if(hmod.eq.8) s4hmod(:,:)=s4(:,:,4) return -end subroutine get_fst240_bitmetrics2 +end subroutine get_fst4_bitmetrics2 diff --git a/lib/fst240/ldpc_240_101_generator.f90 b/lib/fst4/ldpc_240_101_generator.f90 similarity index 100% rename from lib/fst240/ldpc_240_101_generator.f90 rename to lib/fst4/ldpc_240_101_generator.f90 diff --git a/lib/fst240/ldpc_240_101_parity.f90 b/lib/fst4/ldpc_240_101_parity.f90 similarity index 100% rename from lib/fst240/ldpc_240_101_parity.f90 rename to lib/fst4/ldpc_240_101_parity.f90 diff --git a/lib/fst240/ldpc_240_74_generator.f90 b/lib/fst4/ldpc_240_74_generator.f90 similarity index 100% rename from lib/fst240/ldpc_240_74_generator.f90 rename to lib/fst4/ldpc_240_74_generator.f90 diff --git a/lib/fst240/ldpc_240_74_parity.f90 b/lib/fst4/ldpc_240_74_parity.f90 similarity index 100% rename from lib/fst240/ldpc_240_74_parity.f90 rename to lib/fst4/ldpc_240_74_parity.f90 diff --git a/lib/fst240/ldpcsim240_101.f90 b/lib/fst4/ldpcsim240_101.f90 similarity index 100% rename from lib/fst240/ldpcsim240_101.f90 rename to lib/fst4/ldpcsim240_101.f90 diff --git a/lib/fst240/ldpcsim240_74.f90 b/lib/fst4/ldpcsim240_74.f90 similarity index 100% rename from lib/fst240/ldpcsim240_74.f90 rename to lib/fst4/ldpcsim240_74.f90 diff --git a/lib/fst240/osd240_101.f90 b/lib/fst4/osd240_101.f90 similarity index 100% rename from lib/fst240/osd240_101.f90 rename to lib/fst4/osd240_101.f90 diff --git a/lib/fst240/osd240_74.f90 b/lib/fst4/osd240_74.f90 similarity index 100% rename from lib/fst240/osd240_74.f90 rename to lib/fst4/osd240_74.f90 diff --git a/lib/fst240_decode.f90 b/lib/fst4_decode.f90 similarity index 94% rename from lib/fst240_decode.f90 rename to lib/fst4_decode.f90 index 9b52f285e..37ab333a1 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst4_decode.f90 @@ -1,17 +1,17 @@ -module fst240_decode +module fst4_decode - type :: fst240_decoder - procedure(fst240_decode_callback), pointer :: callback + type :: fst4_decoder + procedure(fst4_decode_callback), pointer :: callback contains procedure :: decode - end type fst240_decoder + end type fst4_decoder abstract interface - subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & + subroutine fst4_decode_callback (this,nutc,sync,nsnr,dt,freq, & decoded,nap,qual,ntrperiod,lwspr,fmid,w50) - import fst240_decoder + import fst4_decoder implicit none - class(fst240_decoder), intent(inout) :: this + class(fst4_decoder), intent(inout) :: this integer, intent(in) :: nutc real, intent(in) :: sync integer, intent(in) :: nsnr @@ -24,7 +24,7 @@ module fst240_decode logical, intent(in) :: lwspr real, intent(in) :: fmid real, intent(in) :: w50 - end subroutine fst240_decode_callback + end subroutine fst4_decode_callback end interface contains @@ -36,10 +36,10 @@ contains use timer_module, only: timer use packjt77 use, intrinsic :: iso_c_binding - include 'fst240/fst240_params.f90' + include 'fst4/fst4_params.f90' parameter (MAXCAND=100) - class(fst240_decoder), intent(inout) :: this - procedure(fst240_decode_callback) :: callback + class(fst4_decoder), intent(inout) :: this + procedure(fst4_decode_callback) :: callback character*37 decodes(100) character*37 msg,msgsent character*77 c77 @@ -283,7 +283,7 @@ contains endif ! Get first approximation of candidate frequencies - call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + call get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & minsync,ncand,candidates,base) ndecodes=0 @@ -300,7 +300,7 @@ contains ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown - call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) + call fst4_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) call timer('sync240 ',0) fc1=0.0 @@ -316,7 +316,7 @@ contains do if=-12,12 fc=fc1 + 0.1*baud*if do istart=max(1,is0-ishw),is0+ishw,4*hmod - call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & ntrperiod,fs2,sync) if(sync.gt.smax) then fc2=fc @@ -335,7 +335,7 @@ contains do if=-7,7 fc=fc1 + 0.02*baud*if do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & ntrperiod,fs2,sync) if(sync.gt.smax) then fc2=fc @@ -386,7 +386,7 @@ contains isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 - call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) + call fst4_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) do ijitter=0,jittermax if(ijitter.eq.0) ioffset=0 if(ijitter.eq.1) ioffset=1 @@ -396,9 +396,9 @@ contains cframe=c2(is0:is0+160*nss-1) bitmetrics=0 if(hmod.eq.1) then - call get_fst240_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) + call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) else - call get_fst240_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + call get_fst4_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) endif if(badsync) cycle @@ -538,9 +538,9 @@ contains decodes(ndecodes)=msg if(iwspr.eq.0) then - call get_fst240_tones_from_bits(message101,itone,0) + call get_fst4_tones_from_bits(message101,itone,0) else - call get_fst240_tones_from_bits(message74,itone,1) + call get_fst4_tones_from_bits(message74,itone,1) endif inquire(file='plotspec',exist=ex) fmid=-999.0 @@ -581,12 +581,12 @@ contains return end subroutine decode - subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,ntr,fs,sync) + subroutine sync_fst4(cd0,i0,f0,hmod,ncoh,np,nss,ntr,fs,sync) ! Compute sync power for a complex, downsampled FST240 signal. use timer_module, only: timer - include 'fst240/fst240_params.f90' + include 'fst4/fst4_params.f90' complex cd0(0:np-1) complex csync1,csync2,csynct1,csynct2 complex ctwk(3200) @@ -700,9 +700,9 @@ contains endif sync = s1+s2+s3+s4+s5 return - end subroutine sync_fst240 + end subroutine sync_fst4 - subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) + subroutine fst4_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) ! Output: Complex data in c(), sampled at 12000/ndown Hz @@ -724,9 +724,9 @@ contains call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain return - end subroutine fst240_downsample + end subroutine fst4_downsample - subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + subroutine get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & minsync,ncand,candidates,base) complex c_bigfft(0:nfft1/2) !Full length FFT of raw data @@ -806,13 +806,13 @@ contains enddo return - end subroutine get_candidates_fst240 + end subroutine get_candidates_fst4 subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50) ! On "plotspec" special request, compute Doppler spread for a decoded signal - include 'fst240/fst240_params.f90' + include 'fst4/fst4_params.f90' complex, allocatable :: cwave(:) !Reconstructed complex signal complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper real,allocatable :: ss(:) !Computed power spectrum of g(t) @@ -829,7 +829,7 @@ contains allocate(g(0:nfft-1)) wave=0 fsample=12000.0 - call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave) + call gen_fst4wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave) cwave=cshift(cwave,-i0*ndown) fac=1.0/32768 g(0:nmax-1)=fac*float(iwave)*conjg(cwave(:nmax-1)) @@ -905,4 +905,4 @@ contains return end subroutine write_ref -end module fst240_decode +end module fst4_decode From 580dd85a18040797b97bcb1d8b27d0cec72202cc Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 23 Jul 2020 18:51:05 +0100 Subject: [PATCH 215/239] Remainder of renames to FST4 --- Modulator/Modulator.cpp | 4 +- displayWidgets.txt | 4 +- models/FrequencyList.cpp | 54 ++++++------ models/Modes.cpp | 4 +- models/Modes.hpp | 4 +- widgets/displaytext.cpp | 2 +- widgets/mainwindow.cpp | 186 +++++++++++++++++++-------------------- widgets/mainwindow.h | 8 +- widgets/mainwindow.ui | 18 ++-- widgets/plotter.cpp | 12 +-- widgets/widegraph.cpp | 4 +- 11 files changed, 150 insertions(+), 150 deletions(-) diff --git a/Modulator/Modulator.cpp b/Modulator/Modulator.cpp index 8308a44cb..dbb084ffb 100644 --- a/Modulator/Modulator.cpp +++ b/Modulator/Modulator.cpp @@ -69,8 +69,8 @@ void Modulator::start (QString mode, unsigned symbolsLength, double framesPerSym m_bFastMode=fastMode; m_TRperiod=TRperiod; unsigned delay_ms=1000; - if(mode=="FT8" or (mode=="FST240" and m_nsps==720)) delay_ms=500; //FT8, FST240-15 - if(mode=="FT4") delay_ms=300; //FT4 + if(mode=="FT8" or (mode=="FST4" and m_nsps==720)) delay_ms=500; //FT8, FST4-15 + if(mode=="FT4") delay_ms=300; //FT4 // noise generator parameters if (m_addNoise) { diff --git a/displayWidgets.txt b/displayWidgets.txt index 34750cf98..2f6c382e2 100644 --- a/displayWidgets.txt +++ b/displayWidgets.txt @@ -14,7 +14,7 @@ QRA64 1111100101101101100000000010000000 ISCAT 1001110000000001100000000000000000 MSK144 1011111101000000000100010000000000 WSPR 0000000000000000010100000000000000 -FST240W 0000000000000000010100000000000001 +FST4W 0000000000000000010100000000000001 Echo 0000000000000000000000100000000000 FCal 0011010000000000000000000000010000 FT8 1110100001001110000100001001100010 @@ -61,4 +61,4 @@ Mapping of column numbers to widgets 30. labDXped 31. cbRxAll 32. cbCQonly -33. sbTR_FST240W +33. sbTR_FST4W diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index 74bc0ef64..9b63daaa9 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -46,22 +46,22 @@ namespace {20000000, Modes::FreqCal, IARURegions::ALL}, {136000, Modes::WSPR, IARURegions::ALL}, - {136200, Modes::FST240W, IARURegions::ALL}, + {136200, Modes::FST4W, IARURegions::ALL}, {136130, Modes::JT65, IARURegions::ALL}, {136130, Modes::JT9, IARURegions::ALL}, - {136130, Modes::FST240, IARURegions::ALL}, + {136130, Modes::FST4, IARURegions::ALL}, {474200, Modes::JT65, IARURegions::ALL}, {474200, Modes::JT9, IARURegions::ALL}, - {474200, Modes::FST240, IARURegions::ALL}, + {474200, Modes::FST4, IARURegions::ALL}, {474200, Modes::WSPR, IARURegions::ALL}, - {474400, Modes::FST240W, IARURegions::ALL}, + {474400, Modes::FST4W, IARURegions::ALL}, {1836600, Modes::WSPR, IARURegions::ALL}, - {1836800, Modes::FST240W, IARURegions::ALL}, + {1836800, Modes::FST4W, IARURegions::ALL}, {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations {1839000, Modes::JT9, IARURegions::ALL}, - {1839000, Modes::FST240, IARURegions::ALL}, + {1839000, Modes::FST4, IARURegions::ALL}, {1840000, Modes::FT8, IARURegions::ALL}, // Band plans (all USB dial unless stated otherwise) @@ -93,10 +93,10 @@ namespace // {3570000, Modes::JT65, IARURegions::ALL}, // JA compatible {3572000, Modes::JT9, IARURegions::ALL}, - {3572000, Modes::FST240, IARURegions::ALL}, + {3572000, Modes::FST4, IARURegions::ALL}, {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out - {3568800, Modes::FST240W, IARURegions::ALL}, + {3568800, Modes::FST4W, IARURegions::ALL}, {3575000, Modes::FT4, IARURegions::ALL}, // provisional {3568000, Modes::FT4, IARURegions::R3}, // provisional @@ -132,11 +132,11 @@ namespace // 7110 LSB EMCOMM // {7038600, Modes::WSPR, IARURegions::ALL}, - {7038800, Modes::FST240W, IARURegions::ALL}, + {7038800, Modes::FST4W, IARURegions::ALL}, {7074000, Modes::FT8, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL}, - {7078000, Modes::FST240, IARURegions::ALL}, + {7078000, Modes::FST4, IARURegions::ALL}, {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved // up 500Hz to clear // W1AW code practice QRG @@ -170,9 +170,9 @@ namespace {10136000, Modes::FT8, IARURegions::ALL}, {10138000, Modes::JT65, IARURegions::ALL}, {10138700, Modes::WSPR, IARURegions::ALL}, - {10138900, Modes::FST240W, IARURegions::ALL}, + {10138900, Modes::FST4W, IARURegions::ALL}, {10140000, Modes::JT9, IARURegions::ALL}, - {10140000, Modes::FST240, IARURegions::ALL}, + {10140000, Modes::FST4, IARURegions::ALL}, {10140000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -213,11 +213,11 @@ namespace // 14106.5 OLIVIA 1000 (main QRG) // {14095600, Modes::WSPR, IARURegions::ALL}, - {14095800, Modes::FST240W, IARURegions::ALL}, + {14095800, Modes::FST4W, IARURegions::ALL}, {14074000, Modes::FT8, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL}, - {14078000, Modes::FST240, IARURegions::ALL}, + {14078000, Modes::FST4, IARURegions::ALL}, {14080000, Modes::FT4, IARURegions::ALL}, // provisional // Band plans (all USB dial unless stated otherwise) @@ -250,33 +250,33 @@ namespace {18100000, Modes::FT8, IARURegions::ALL}, {18102000, Modes::JT65, IARURegions::ALL}, {18104000, Modes::JT9, IARURegions::ALL}, - {18104000, Modes::FST240, IARURegions::ALL}, + {18104000, Modes::FST4, IARURegions::ALL}, {18104000, Modes::FT4, IARURegions::ALL}, // provisional {18104600, Modes::WSPR, IARURegions::ALL}, - {18104800, Modes::FST240W, IARURegions::ALL}, + {18104800, Modes::FST4W, IARURegions::ALL}, {21074000, Modes::FT8, IARURegions::ALL}, {21076000, Modes::JT65, IARURegions::ALL}, {21078000, Modes::JT9, IARURegions::ALL}, - {21078000, Modes::FST240, IARURegions::ALL}, + {21078000, Modes::FST4, IARURegions::ALL}, {21094600, Modes::WSPR, IARURegions::ALL}, - {21094800, Modes::FST240W, IARURegions::ALL}, + {21094800, Modes::FST4W, IARURegions::ALL}, {21140000, Modes::FT4, IARURegions::ALL}, {24915000, Modes::FT8, IARURegions::ALL}, {24917000, Modes::JT65, IARURegions::ALL}, {24919000, Modes::JT9, IARURegions::ALL}, - {24919000, Modes::FST240, IARURegions::ALL}, + {24919000, Modes::FST4, IARURegions::ALL}, {24919000, Modes::FT4, IARURegions::ALL}, // provisional {24924600, Modes::WSPR, IARURegions::ALL}, - {24924800, Modes::FST240W, IARURegions::ALL}, + {24924800, Modes::FST4W, IARURegions::ALL}, {28074000, Modes::FT8, IARURegions::ALL}, {28076000, Modes::JT65, IARURegions::ALL}, {28078000, Modes::JT9, IARURegions::ALL}, - {28078000, Modes::FST240, IARURegions::ALL}, + {28078000, Modes::FST4, IARURegions::ALL}, {28124600, Modes::WSPR, IARURegions::ALL}, - {28124800, Modes::FST240W, IARURegions::ALL}, + {28124800, Modes::FST4W, IARURegions::ALL}, {28180000, Modes::FT4, IARURegions::ALL}, {50200000, Modes::Echo, IARURegions::ALL}, @@ -287,11 +287,11 @@ namespace {50260000, Modes::MSK144, IARURegions::R3}, {50293000, Modes::WSPR, IARURegions::R2}, {50293000, Modes::WSPR, IARURegions::R3}, - {50293200, Modes::FST240W, IARURegions::R2}, - {50293200, Modes::FST240W, IARURegions::R3}, + {50293200, Modes::FST4W, IARURegions::R2}, + {50293200, Modes::FST4W, IARURegions::R3}, {50310000, Modes::JT65, IARURegions::ALL}, {50312000, Modes::JT9, IARURegions::ALL}, - {50312000, Modes::FST240, IARURegions::ALL}, + {50312000, Modes::FST4, IARURegions::ALL}, {50313000, Modes::FT8, IARURegions::ALL}, {50318000, Modes::FT4, IARURegions::ALL}, // provisional {50323000, Modes::FT8, IARURegions::ALL}, @@ -300,7 +300,7 @@ namespace {70102000, Modes::JT65, IARURegions::R1}, {70104000, Modes::JT9, IARURegions::R1}, {70091000, Modes::WSPR, IARURegions::R1}, - {70091200, Modes::FST240W, IARURegions::R2}, + {70091200, Modes::FST4W, IARURegions::R2}, {70230000, Modes::MSK144, IARURegions::R1}, {144120000, Modes::JT65, IARURegions::ALL}, @@ -310,7 +310,7 @@ namespace {144360000, Modes::MSK144, IARURegions::R1}, {144150000, Modes::MSK144, IARURegions::R2}, {144489000, Modes::WSPR, IARURegions::ALL}, - {144489200, Modes::FST240W, IARURegions::R2}, + {144489200, Modes::FST4W, IARURegions::R2}, {144120000, Modes::QRA64, IARURegions::ALL}, {222065000, Modes::Echo, IARURegions::R2}, diff --git a/models/Modes.cpp b/models/Modes.cpp index d337fafd5..2de1f7c90 100644 --- a/models/Modes.cpp +++ b/models/Modes.cpp @@ -25,8 +25,8 @@ namespace "FreqCal", "FT8", "FT4", - "FST240", - "FST240W" + "FST4", + "FST4W" }; std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]); } diff --git a/models/Modes.hpp b/models/Modes.hpp index deb22865f..ac57ba4ad 100644 --- a/models/Modes.hpp +++ b/models/Modes.hpp @@ -50,8 +50,8 @@ public: FreqCal, FT8, FT4, - FST240, - FST240W, + FST4, + FST4W, MODES_END_SENTINAL_AND_COUNT // this must be last }; Q_ENUM (Mode) diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 2f19774de..d498f180e 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -486,7 +486,7 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx if(modeTx=="JT4") t1=" $ "; if(modeTx=="JT65") t1=" # "; if(modeTx=="MSK144") t1=" & "; - if(modeTx=="FST240") t1=" ` "; + if(modeTx=="FST4") t1=" ` "; QString t2; t2 = t2.asprintf("%4d",txFreq); QString t; diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 43b6dbabd..64a80259e 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -105,7 +105,7 @@ extern "C" { void genft4_(char* msg, int* ichk, char* msgsent, char ft4msgbits[], int itone[], fortran_charlen_t, fortran_charlen_t); - void genfst240_(char* msg, int* ichk, char* msgsent, char fst240msgbits[], + void genfst4_(char* msg, int* ichk, char* msgsent, char fst4msgbits[], int itone[], int* iwspr, fortran_charlen_t, fortran_charlen_t); void gen_ft8wave_(int itone[], int* nsym, int* nsps, float* bt, float* fsample, float* f0, @@ -114,7 +114,7 @@ extern "C" { void gen_ft4wave_(int itone[], int* nsym, int* nsps, float* fsample, float* f0, float xjunk[], float wave[], int* icmplx, int* nwave); - void gen_fst240wave_(int itone[], int* nsym, int* nsps, int* nwave, float* fsample, + void gen_fst4wave_(int itone[], int* nsym, int* nsps, int* nwave, float* fsample, int* hmod, float* f0, int* icmplx, float xjunk[], float wave[]); void gen4_(char* msg, int* ichk, char* msgsent, int itone[], @@ -428,7 +428,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300, 900, 1800}); - ui->sbTR_FST240W->values ({15, 30, 60, 120, 300, 900, 1800}); + ui->sbTR_FST4W->values ({15, 30, 60, 120, 300, 900, 1800}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); @@ -579,8 +579,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, on_EraseButton_clicked (); QActionGroup* modeGroup = new QActionGroup(this); - ui->actionFST240->setActionGroup(modeGroup); - ui->actionFST240W->setActionGroup(modeGroup); + ui->actionFST4->setActionGroup(modeGroup); + ui->actionFST4W->setActionGroup(modeGroup); ui->actionFT4->setActionGroup(modeGroup); ui->actionFT8->setActionGroup(modeGroup); ui->actionJT9->setActionGroup(modeGroup); @@ -1045,7 +1045,7 @@ void MainWindow::on_the_minute () } } - if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W") { + if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST4W") { if (m_idleMinutes < m_config.watchdog ()) ++m_idleMinutes; update_watchdog_label (); } else { @@ -1122,7 +1122,7 @@ void MainWindow::writeSettings() m_settings->setValue("NoOwnCall",ui->cbNoOwnCall->isChecked()); m_settings->setValue ("BandHopping", ui->band_hopping_group_box->isChecked ()); m_settings->setValue ("TRPeriod", ui->sbTR->value ()); - m_settings->setValue ("TRPeriod_FST240W", ui->sbTR_FST240W->value ()); + m_settings->setValue ("TRPeriod_FST4W", ui->sbTR_FST4W->value ()); m_settings->setValue("FastMode",m_bFastMode); m_settings->setValue("Fast9",m_bFast9); m_settings->setValue ("CQTxfreq", ui->sbCQTxFreq->value ()); @@ -1197,7 +1197,7 @@ void MainWindow::readSettings() m_bFast9=m_settings->value("Fast9",false).toBool(); m_bFastMode=m_settings->value("FastMode",false).toBool(); ui->sbTR->setValue (m_settings->value ("TRPeriod", 15).toInt()); - ui->sbTR_FST240W->setValue (m_settings->value ("TRPeriod_FST240W", 15).toInt()); + ui->sbTR_FST4W->setValue (m_settings->value ("TRPeriod_FST4W", 15).toInt()); m_lastMonitoredFrequency = m_settings->value ("DialFreq", QVariant::fromValue (default_frequency)).value (); ui->WSPRfreqSpinBox->setValue(0); // ensure a change is signaled @@ -1341,7 +1341,7 @@ void MainWindow::fixStop() m_hsymStop=50; } else if (m_mode=="FT4") { m_hsymStop=21; - } else if(m_mode=="FST240" or m_mode=="FST240W") { + } else if(m_mode=="FST4" or m_mode=="FST4W") { int stop[] = {39,85,187,387,1003,3107,6232}; int stop_EME[] = {48,95,197,396,1012,3107,6232}; int i=0; @@ -1396,10 +1396,10 @@ void MainWindow::dataSink(qint64 frames) int nsmo=m_wideGraph->smoothYellow()-1; bool bLowSidelobes=m_config.lowSidelobes(); int npct=0; - if(m_mode.startsWith("FST240")) npct=ui->sbNB->value(); + if(m_mode.startsWith("FST4")) npct=ui->sbNB->value(); symspec_(&dec_data,&k,&m_TRperiod,&nsps,&m_inGain,&bLowSidelobes,&nsmo,&m_px,s, &m_df3,&m_ihsym,&m_npts8,&m_pxmax,&npct); - if(m_mode=="WSPR" or m_mode=="FST240W") wspr_downsample_(dec_data.d2,&k); + if(m_mode=="WSPR" or m_mode=="FST4W") wspr_downsample_(dec_data.d2,&k); if(m_ihsym <=0) return; if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer if(m_monitoring || m_diskData) { @@ -1506,7 +1506,7 @@ void MainWindow::dataSink(qint64 frames) if(m_mode!="WSPR") decode(); //Start decoder if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return; - if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST240W")) { + if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST4W")) { //Always save unless "Save None"; may delete later if(m_TRperiod < 60) { int n=fmod(double(now.time().second()),m_TRperiod); @@ -1525,7 +1525,7 @@ void MainWindow::dataSink(qint64 frames) m_saveWAVWatcher.setFuture (QtConcurrent::run (std::bind (&MainWindow::save_wave_file, this, m_fnameWE, &dec_data.d2[0], samples, m_config.my_callsign(), m_config.my_grid(), m_mode, m_nSubMode, m_freqNominal, m_hisCall, m_hisGrid))); - if (m_mode=="WSPR" or m_mode=="FST240W") { + if (m_mode=="WSPR" or m_mode=="FST4W") { QString c2name_string {m_fnameWE + ".c2"}; int len1=c2name_string.length(); char c2name[80]; @@ -1587,7 +1587,7 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int auto source = QString {"%1, %2"}.arg (my_callsign).arg (my_grid); auto comment = QString {"Mode=%1%2, Freq=%3%4"} .arg (mode) - .arg (QString {(mode.contains ('J') && !mode.contains ('+')) || mode.startsWith ("FST240") + .arg (QString {(mode.contains ('J') && !mode.contains ('+')) || mode.startsWith ("FST4") ? QString {", Sub Mode="} + QChar {'A' + sub_mode} : QString {}}) .arg (Radio::frequency_MHz_string (frequency)) @@ -1794,7 +1794,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog m_config.transceiver_online (); if(!m_bFastMode) setXIT (ui->TxFreqSpinBox->value ()); - if ((m_config.single_decode () && !m_mode.startsWith ("FST240")) || m_mode=="JT4") { + if ((m_config.single_decode () && !m_mode.startsWith ("FST4")) || m_mode=="JT4") { ui->label_6->setText(tr ("Single-Period Decodes")); ui->label_7->setText(tr ("Average Decodes")); } @@ -1879,7 +1879,7 @@ void MainWindow::on_autoButton_clicked (bool checked) m_nclearave=1; echocom_.nsum=0; } - if(m_mode=="WSPR" or m_mode=="FST240W") { + if(m_mode=="WSPR" or m_mode=="FST4W") { QPalette palette {ui->sbTxPercent->palette ()}; if(m_auto or m_pctx==0) { palette.setColor(QPalette::Base,Qt::white); @@ -2317,9 +2317,9 @@ void MainWindow::setup_status_bar (bool vhf) mode_label.setStyleSheet ("QLabel{background-color: #ff0099}"); } else if ("FT8" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff6699}"); - } else if ("FST240" == m_mode) { + } else if ("FST4" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #99ff66}"); - } else if ("FST240W" == m_mode) { + } else if ("FST4W" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #6699ff}"); } else if ("FreqCal" == m_mode) { mode_label.setStyleSheet ("QLabel{background-color: #ff9933}"); @@ -2537,7 +2537,7 @@ void MainWindow::hideMenus(bool checked) minimumSize().setWidth(770); } ui->menuBar->setVisible(!checked); - if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="FSt240W") { + if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="Fst4W") { ui->label_6->setVisible(!checked); ui->label_7->setVisible(!checked); ui->decodedTextLabel2->setVisible(!checked); @@ -2902,7 +2902,7 @@ void MainWindow::decode() //decode() dec_data.params.nutc=100*ihr + imin; if(m_TRperiod < 60) { qint64 ms=1000.0*(2.0-m_TRperiod); - if(m_mode=="FST240") ms=1000.0*(6.0-m_TRperiod); + if(m_mode=="FST4") ms=1000.0*(6.0-m_TRperiod); //Adjust for FT8 early decode: if(m_mode=="FT8" and m_ihsym==m_earlyDecode and !m_diskData) ms+=(m_hsymStop-m_earlyDecode)*288; if(m_mode=="FT8" and m_ihsym==m_earlyDecode2 and !m_diskData) ms+=(m_hsymStop-m_earlyDecode2)*288; @@ -2972,8 +2972,8 @@ void MainWindow::decode() //decode() dec_data.params.nmode=5; m_BestCQpriority=""; } - if(m_mode=="FST240") dec_data.params.nmode=240; - if(m_mode=="FST240W") dec_data.params.nmode=241; + if(m_mode=="FST4") dec_data.params.nmode=240; + if(m_mode=="FST4W") dec_data.params.nmode=241; dec_data.params.ntrperiod=m_TRperiod; dec_data.params.nsubmode=m_nSubMode; if(m_mode=="QRA64") dec_data.params.nsubmode=100 + m_nSubMode; @@ -2990,7 +2990,7 @@ void MainWindow::decode() //decode() dec_data.params.nexp_decode = static_cast (m_config.special_op_id()); if(m_config.single_decode()) dec_data.params.nexp_decode += 32; if(m_config.enable_VHF_features()) dec_data.params.nexp_decode += 64; - if(m_mode.startsWith("FST240")) dec_data.params.nexp_decode += 256*ui->sbNB->value(); + if(m_mode.startsWith("FST4")) dec_data.params.nexp_decode += 256*ui->sbNB->value(); ::memcpy(dec_data.params.datetime, m_dateTime.toLatin1()+" ", sizeof dec_data.params.datetime); ::memcpy(dec_data.params.mycall, (m_config.my_callsign()+" ").toLatin1(), sizeof dec_data.params.mycall); @@ -3149,7 +3149,7 @@ void MainWindow::readFromStdout() //readFromStdout } bool haveFSpread {false}; float fSpread {0.}; - if (m_mode.startsWith ("FST240")) + if (m_mode.startsWith ("FST4")) { auto text = line_read.mid (64, 6).trimmed (); if (text.size ()) @@ -3268,7 +3268,7 @@ void MainWindow::readFromStdout() //readFromStdout //Right (Rx Frequency) window bool bDisplayRight=bAvgMsg; int audioFreq=decodedtext.frequencyOffset(); - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") { + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST4") { auto const& parts = decodedtext.string().remove("<").remove(">") .split (' ', SkipEmptyParts); if (parts.size() > 6) { @@ -3352,7 +3352,7 @@ void MainWindow::readFromStdout() //readFromStdout //### I think this is where we are preventing Hounds from spotting Fox ### if(m_mode!="FT8" or (SpecOp::HOUND != m_config.special_op_id())) { if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="QRA64" or m_mode=="JT4" - or m_mode=="JT65" or m_mode=="JT9" or m_mode=="FST240") { + or m_mode=="JT65" or m_mode=="JT9" or m_mode=="FST4") { auto_sequence (decodedtext, 25, 50); } @@ -3370,12 +3370,12 @@ void MainWindow::readFromStdout() //readFromStdout // extract details and send to PSKreporter int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged; bool okToPost=(nsec > int(4*m_TRperiod)/5); - if(m_mode=="FST240W" and okToPost) { + if(m_mode=="FST4W" and okToPost) { line_read=line_read.left(22) + " CQ " + line_read.trimmed().mid(22); int n=line_read.trimmed().size(); line_read=line_read.trimmed().left(n-3); - DecodedText FST240W_post {QString::fromUtf8(line_read.constData())}; - pskPost(FST240W_post); + DecodedText FST4W_post {QString::fromUtf8(line_read.constData())}; + pskPost(FST4W_post); } else { if (stdMsg && okToPost) pskPost(decodedtext); } @@ -3497,7 +3497,7 @@ void MainWindow::killFile () if (m_fnameWE.size () && !(m_saveAll || (m_saveDecoded && m_bDecoded))) { QFile f1 {m_fnameWE + ".wav"}; if(f1.exists()) f1.remove(); - if(m_mode=="WSPR" or m_mode=="FST240W") { + if(m_mode=="WSPR" or m_mode=="FST4W") { QFile f2 {m_fnameWE + ".c2"}; if(f2.exists()) f2.remove(); } @@ -3508,7 +3508,7 @@ void MainWindow::on_EraseButton_clicked () { qint64 ms=QDateTime::currentMSecsSinceEpoch(); ui->decodedTextBrowser2->erase (); - if(m_mode=="WSPR" or m_mode=="Echo" or m_mode=="ISCAT" or m_mode=="FST240W") { + if(m_mode=="WSPR" or m_mode=="Echo" or m_mode=="ISCAT" or m_mode=="FST4W") { ui->decodedTextBrowser->erase (); } else { if((ms-m_msErase)<500) { @@ -3562,7 +3562,7 @@ void MainWindow::guiUpdate() if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65 if(m_modeTx=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64 if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR - if(m_modeTx=="FST240" or m_mode=="FST240W") { //FST240, FST240W + if(m_modeTx=="FST4" or m_mode=="FST4W") { //FST4, FST4W if(m_TRperiod==15) txDuration=1.0 + 160*720/12000.0; if(m_TRperiod==30) txDuration=1.0 + 160*1680/12000.0; if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; @@ -3581,7 +3581,7 @@ void MainWindow::guiUpdate() if((icw[0]>0) and (!m_bFast9)) tx2 += icw[0]*2560.0/48000.0; //Full length including CW ID if(tx2>m_TRperiod) tx2=m_TRperiod; - if(!m_txFirst and m_mode!="WSPR" and m_mode!="FST240W") { + if(!m_txFirst and m_mode!="WSPR" and m_mode!="FST4W") { tx1 += m_TRperiod; tx2 += m_TRperiod; } @@ -3602,7 +3602,7 @@ void MainWindow::guiUpdate() if(m_transmitting) m_bEchoTxed=true; } - if(m_mode=="WSPR" or m_mode=="FST240W") { + if(m_mode=="WSPR" or m_mode=="FST4W") { if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx m_tuneup=false; //This is not an ATU tuneup if(ui->sbTxPercent->isEnabled () && m_pctx==0) m_WSPR_tx_next = false; //Don't transmit if m_pctx=0 @@ -3615,16 +3615,16 @@ void MainWindow::guiUpdate() m_ntr=-1; //This says we will have transmitted m_txNext=false; ui->pbTxNext->setChecked(false); - m_bTxTime=true; //Start a WSPR or FST240W Tx sequence + m_bTxTime=true; //Start a WSPR or FST4W Tx sequence } else { -// This will be a WSPR or FST240W Rx sequence. +// This will be a WSPR or FST4W Rx sequence. m_ntr=1; //This says we will have received - m_bTxTime=false; //Start a WSPR or FST240W Rx sequence + m_bTxTime=false; //Start a WSPR or FST4W Rx sequence } } } else { -// For all modes other than WSPR and FSt240W +// For all modes other than WSPR and Fst4W m_bTxTime = (t2p >= tx1) and (t2p < tx2); if(m_mode=="Echo") m_bTxTime = m_bTxTime and m_bEchoTxOK; if(m_mode=="FT8" and ui->tx5->currentText().contains("/B ")) { @@ -3677,7 +3677,7 @@ void MainWindow::guiUpdate() } } - if (m_config.watchdog() && m_mode!="WSPR" && m_mode!="FST240W" + if (m_config.watchdog() && m_mode!="WSPR" && m_mode!="FST4W" && m_idleMinutes >= m_config.watchdog ()) { tx_watchdog (true); // disable transmit } @@ -3749,19 +3749,19 @@ void MainWindow::guiUpdate() if(!m_bTxTime and !m_tune) m_btxok=false; //Time to stop transmitting } - if((m_mode=="WSPR" or m_mode=="FST240W") and + if((m_mode=="WSPR" or m_mode=="FST4W") and ((m_ntr==1 and m_rxDone) or (m_ntr==-1 and m_nseq>tx2))) { if(m_monitoring) { m_rxDone=false; } if(m_transmitting) { WSPR_history(m_freqNominal,-1); - m_bTxTime=false; //Time to stop a WSPR or FST240W transmission + m_bTxTime=false; //Time to stop a WSPR or FST4W transmission m_btxok=false; } else if (m_ntr != -1) { WSPR_scheduling (); - m_ntr=0; //This WSPR or FST240W Rx sequence is complete + m_ntr=0; //This WSPR or FST4W Rx sequence is complete } } @@ -3823,7 +3823,7 @@ void MainWindow::guiUpdate() if(m_modeTx=="WSPR") genwspr_(message, msgsent, const_cast (itone), 22, 22); if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4" - or m_modeTx=="FST240" or m_modeTx=="FST240W") { + or m_modeTx=="FST4" or m_modeTx=="FST4W") { char MyCall[6]; char MyGrid[6]; ::memcpy(MyCall, (m_config.my_callsign()+" ").toLatin1(), sizeof MyCall); @@ -3883,18 +3883,18 @@ void MainWindow::guiUpdate() gen_ft4wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave, foxcom_.wave,&icmplx,&nwave); } - if(m_modeTx=="FST240" or m_modeTx=="FST240W") { + if(m_modeTx=="FST4" or m_modeTx=="FST4W") { int ichk=0; int iwspr=0; - char fst240msgbits[101]; + char fst4msgbits[101]; QString wmsg; - if(m_mode=="FST240W") { + if(m_mode=="FST4W") { iwspr = 1; wmsg=WSPR_message(); ba=wmsg.toLatin1(); ba2msg(ba,message); } - genfst240_(message,&ichk,msgsent,const_cast (fst240msgbits), + genfst4_(message,&ichk,msgsent,const_cast (fst4msgbits), const_cast(itone), &iwspr, 37, 37); int hmod=int(pow(2.0,double(m_nSubMode))); int nsps=720; @@ -3911,7 +3911,7 @@ void MainWindow::guiUpdate() float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; int nwave=(nsym+2)*nsps; int icmplx=0; - gen_fst240wave_(const_cast(itone),&nsym,&nsps,&nwave, + gen_fst4wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); } @@ -4043,7 +4043,7 @@ void MainWindow::guiUpdate() } if (g_iptt == 1 && m_iptt0 == 0) { auto const& current_message = QString::fromLatin1 (msgsent); - if(m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W" + if(m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST4W" && current_message != m_msgSent0) { tx_watchdog (false); // in case we are auto sequencing m_msgSent0 = current_message; @@ -4232,7 +4232,7 @@ void MainWindow::startTx2() ui->signal_meter_widget->setValue(0,0); if(m_mode=="Echo" and !m_tune) m_bTransmittedEcho=true; - if((m_mode=="WSPR" or m_mode=="FST240W") and !m_tune) { + if((m_mode=="WSPR" or m_mode=="FST4W") and !m_tune) { if (m_config.TX_messages ()) { t = " Transmitting " + m_mode + " ----------------------- " + m_config.bands ()->find (m_freqNominal); @@ -4268,7 +4268,7 @@ void MainWindow::stopTx2() on_stopTxButton_clicked (); m_nTx73 = 0; } - if(((m_mode=="WSPR" or m_mode=="FST240W") and m_ntr==-1) and !m_tuneup) { + if(((m_mode=="WSPR" or m_mode=="FST4W") and m_ntr==-1) and !m_tuneup) { m_wideGraph->setWSPRtransmitted(); WSPR_scheduling (); m_ntr=0; @@ -4540,7 +4540,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie || ("JT9" == m_mode && mode != "@") || ("MSK144" == m_mode && !("&" == mode || "^" == mode)) || ("QRA64" == m_mode && mode.left (1) != ":")) { - return; //Currently we do auto-sequencing only in FT4, FT8, MSK144, and FST240 + return; //Currently we do auto-sequencing only in FT4, FT8, MSK144, and FST4 } //Skip the rest if no decoded text extracted @@ -5159,7 +5159,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=="FST240") { + if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4" || m_mode=="FST4") { QString t2,t3; QString sent=rpt; QString rs,rst; @@ -5239,7 +5239,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } t=t0 + (m_send_RR73 ? "RR73" : "RRR"); - if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST240") { + if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST4") { if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> " + (m_send_RR73 ? "RR73" : "RRR"); if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " " + (m_send_RR73 ? "RR73" : "RRR"); } @@ -5247,7 +5247,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) msgtype(t, ui->tx4); t=t0 + "73"; - if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST240") { + if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4" || m_mode == "FST4") { if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> 73"; if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " 73"; } @@ -5263,7 +5263,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144" || m_mode == "FST240") return; + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144" || m_mode == "FST4") return; if (is_compound) { if (is_type_one) { @@ -5823,7 +5823,7 @@ void MainWindow::displayWidgets(qint64 n) if(i==30) ui->labDXped->setVisible(b); if(i==31) ui->cbRxAll->setVisible(b); if(i==32) ui->cbCQonly->setVisible(b); - if(i==33) ui->sbTR_FST240W->setVisible(b); + if(i==33) ui->sbTR_FST4W->setVisible(b); j=j>>1; } ui->pbBestSP->setVisible(m_mode=="FT4"); @@ -5836,12 +5836,12 @@ void MainWindow::displayWidgets(qint64 n) if(m_mode=="MSK144") b=SpecOp::EU_VHF==m_config.special_op_id(); ui->sbSerialNumber->setVisible(b); m_lastCallsign.clear (); // ensures Tx5 is updated for new modes - b=m_mode.startsWith("FST240"); + b=m_mode.startsWith("FST4"); ui->sbNB->setVisible(b); genStdMsgs (m_rpt, true); } -void MainWindow::on_actionFST240_triggered() +void MainWindow::on_actionFST4_triggered() { int nsub=m_nSubMode; on_actionJT65_triggered(); @@ -5850,9 +5850,9 @@ void MainWindow::on_actionFST240_triggered() ui->sbSubmode->setMaximum(3); m_nSubMode=nsub; ui->sbSubmode->setValue(m_nSubMode); - m_mode="FST240"; - m_modeTx="FST240"; - ui->actionFST240->setChecked(true); + m_mode="FST4"; + m_modeTx="FST4"; + ui->actionFST4->setChecked(true); WSPR_config(false); bool bVHF=m_config.enable_VHF_features(); // 0123456789012345678901234567890123 @@ -5865,18 +5865,18 @@ void MainWindow::on_actionFST240_triggered() m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setPeriod(m_TRperiod,6912); m_wideGraph->setTxFreq(ui->TxFreqSpinBox->value()); - switch_mode (Modes::FST240); + switch_mode (Modes::FST4); m_wideGraph->setMode(m_mode); statusChanged(); } -void MainWindow::on_actionFST240W_triggered() +void MainWindow::on_actionFST4W_triggered() { - on_actionFST240_triggered(); - m_mode="FST240W"; - m_modeTx="FST240W"; + on_actionFST4_triggered(); + m_mode="FST4W"; + m_modeTx="FST4W"; WSPR_config(true); - ui->actionFST240W->setChecked(true); + ui->actionFST4W->setChecked(true); // 0123456789012345678901234567890123 displayWidgets(nWidgets("0000000000000000010100000000000001")); bool bVHF=m_config.enable_VHF_features(); @@ -5885,7 +5885,7 @@ void MainWindow::on_actionFST240W_triggered() ui->sbSubmode->setValue(m_nSubMode); ui->band_hopping_group_box->setChecked(false); ui->band_hopping_group_box->setVisible(false); - on_sbTR_FST240W_valueChanged (ui->sbTR_FST240W->value ()); + on_sbTR_FST4W_valueChanged (ui->sbTR_FST4W->value ()); ui->sbSubmode->setMaximum(3); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); @@ -5893,7 +5893,7 @@ void MainWindow::on_actionFST240W_triggered() m_wideGraph->setTxFreq(ui->WSPRfreqSpinBox->value()); ui->sbFtol->setValue(100); ui->RxFreqSpinBox->setValue(1500); - switch_mode (Modes::FST240W); + switch_mode (Modes::FST4W); statusChanged(); } @@ -6125,7 +6125,7 @@ void MainWindow::on_actionJT9_triggered() ui->decodedTextLabel2->setText(" UTC dB T Freq " + tr ("Message")); } else { ui->cbAutoSeq->setChecked(false); - if (m_mode != "FST240") + if (m_mode != "FST4") { m_TRperiod=60.0; ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); @@ -6186,8 +6186,8 @@ void MainWindow::on_actionJT9_JT65_triggered() void MainWindow::on_actionJT65_triggered() { - if(m_mode=="JT4" or m_mode=="WSPR" or m_mode=="FST240W") { -// If coming from JT4, WSPR, or FST240W mode, pretend temporarily that we're coming + if(m_mode=="JT4" or m_mode=="WSPR" or m_mode=="FST4W") { +// If coming from JT4, WSPR, or FST4W mode, pretend temporarily that we're coming // from JT9 and click the pbTxMode button m_modeTx="JT9"; on_pbTxMode_clicked(); @@ -6317,8 +6317,8 @@ void MainWindow::on_actionMSK144_triggered() if("WSPR"==m_mode) ui->actionWSPR->setChecked(true); if("Echo"==m_mode) ui->actionEcho->setChecked(true); if("FreqCal"==m_mode) ui->actionFreqCal->setChecked(true); - if("FST240"==m_mode) ui->actionFST240->setChecked(true); - if("FST240W"==m_mode) ui->actionFST240W->setChecked(true); + if("FST4"==m_mode) ui->actionFST4->setChecked(true); + if("FST4W"==m_mode) ui->actionFST4W->setChecked(true); // Make sure that MSK144 is not checked. ui->actionMSK144->setChecked(false); MessageBox::warning_message (this, tr ("Improper mode"), @@ -6507,9 +6507,9 @@ void MainWindow::WSPR_config(bool b) ui->logQSOButton->setVisible(!b); ui->DecodeButton->setEnabled(!b); ui->band_hopping_group_box->setVisible(true); - ui->RoundRobin->setVisible(m_mode=="FST240W"); + ui->RoundRobin->setVisible(m_mode=="FST4W"); ui->RoundRobin->lineEdit()->setAlignment(Qt::AlignCenter); - if(b and m_mode!="Echo" and m_mode!="FST240W") { + if(b and m_mode!="Echo" and m_mode!="FST4W") { QString t="UTC dB DT Freq Drift Call Grid dBm "; if(m_config.miles()) t += " mi"; if(!m_config.miles()) t += " km"; @@ -6728,7 +6728,7 @@ void MainWindow::band_changed (Frequency f) void MainWindow::enable_DXCC_entity (bool on) { - if (on and m_mode!="WSPR" and m_mode!="FST240W" and m_mode!="Echo") { + if (on and m_mode!="WSPR" and m_mode!="FST4W" and m_mode!="Echo") { //m_logBook.init(); // re-read the log and cty.dat files // ui->gridLayout->setColumnStretch(0,55); // adjust proportions of text displays // ui->gridLayout->setColumnStretch(1,45); @@ -7012,7 +7012,7 @@ void MainWindow::setXIT(int n, Frequency base) void MainWindow::setFreq4(int rxFreq, int txFreq) { if (ui->RxFreqSpinBox->isEnabled ()) ui->RxFreqSpinBox->setValue(rxFreq); - if(m_mode=="WSPR" or m_mode=="FST240W") { + if(m_mode=="WSPR" or m_mode=="FST4W") { ui->WSPRfreqSpinBox->setValue(txFreq); } else { if (ui->TxFreqSpinBox->isEnabled ()) { @@ -7189,7 +7189,7 @@ void MainWindow::transmit (double snr) true, false, snr, m_TRperiod); } - if (m_modeTx == "FST240" or m_modeTx == "FST240W") { + if (m_modeTx == "FST4" or m_modeTx == "FST4W") { m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. int nsps=720; @@ -7203,7 +7203,7 @@ void MainWindow::transmit (double snr) double dfreq=hmod*12000.0/nsps; double f0=ui->WSPRfreqSpinBox->value() - m_XIT; if(!m_tune) f0 += + 1.5*dfreq; - Q_EMIT sendMessage (m_mode, NUM_FST240_SYMBOLS,double(nsps),f0,toneSpacing, + Q_EMIT sendMessage (m_mode, NUM_FST4_SYMBOLS,double(nsps),f0,toneSpacing, m_soundOutput,m_config.audio_output_channel(), true, false, snr, m_TRperiod); } @@ -7395,7 +7395,7 @@ void MainWindow::transmitDisplay (bool transmitting) ui->pbT2R->setEnabled (QSY_allowed); } - if (m_mode!="WSPR" and m_mode!="FST240W") { + if (m_mode!="WSPR" and m_mode!="FST4W") { if(m_config.enable_VHF_features ()) { ui->TxFreqSpinBox->setEnabled (true); } else { @@ -7448,14 +7448,14 @@ void::MainWindow::VHF_features_enabled(bool b) void MainWindow::on_sbTR_valueChanged(int value) { // if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode; - if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST240" or m_mode=="FST240W") { + if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST4" or m_mode=="FST4W") { m_TRperiod = value; - if (m_mode == "FST240" || m_mode == "FST240W") + if (m_mode == "FST4" || m_mode == "FST4W") { if (m_TRperiod < 60) { ui->decodedTextLabel->setText(" UTC dB DT Freq " + tr ("Message")); - if (m_mode != "FST240W") + if (m_mode != "FST4W") { ui->decodedTextLabel2->setText(" UTC dB DT Freq " + tr ("Message")); } @@ -7463,7 +7463,7 @@ void MainWindow::on_sbTR_valueChanged(int value) else { ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message")); - if (m_mode != "FST240W") + if (m_mode != "FST4W") { ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message")); } @@ -7485,7 +7485,7 @@ void MainWindow::on_sbTR_valueChanged(int value) statusUpdate (); } -void MainWindow::on_sbTR_FST240W_valueChanged(int value) +void MainWindow::on_sbTR_FST4W_valueChanged(int value) { on_sbTR_valueChanged(value); } @@ -7965,7 +7965,7 @@ void MainWindow::on_pbTxNext_clicked(bool b) void MainWindow::WSPR_scheduling () { QString t=ui->RoundRobin->currentText(); - if(m_mode=="FST240W" and t!="Random") { + if(m_mode=="FST4W" and t!="Random") { int i=t.left (1).toInt () - 1; int n=t.right(1).toInt(); @@ -8019,7 +8019,7 @@ void MainWindow::WSPR_scheduling () band_hopping_label.setText (hop_data.period_name_); } else { - m_WSPR_tx_next = m_WSPR_band_hopping.next_is_tx(m_mode=="FST240W"); + m_WSPR_tx_next = m_WSPR_band_hopping.next_is_tx(m_mode=="FST4W"); } } @@ -8274,7 +8274,7 @@ void MainWindow::tx_watchdog (bool triggered) void MainWindow::update_watchdog_label () { - if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST240W") + if (m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST4W") { watchdog_label.setText (tr ("WD:%1m").arg (m_config.watchdog () - m_idleMinutes)); watchdog_label.setVisible (true); @@ -8311,7 +8311,7 @@ void MainWindow::on_cbFirst_toggled(bool b) void MainWindow::on_cbAutoSeq_toggled(bool b) { if(!b) ui->cbFirst->setChecked(false); - ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST240") and b); + ui->cbFirst->setVisible((m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST4") and b); } void MainWindow::on_measure_check_box_stateChanged (int state) @@ -9088,8 +9088,8 @@ void MainWindow::on_pbBestSP_clicked() void MainWindow::set_mode (QString const& mode) { if ("FT4" == mode) on_actionFT4_triggered (); - else if ("FST240" == mode) on_actionFST240_triggered (); - else if ("FST240W" == mode) on_actionFST240W_triggered (); + else if ("FST4" == mode) on_actionFST4_triggered (); + else if ("FST4W" == mode) on_actionFST4W_triggered (); else if ("FT8" == mode) on_actionFT8_triggered (); else if ("JT4" == mode) on_actionJT4_triggered (); else if ("JT9" == mode) on_actionJT9_triggered (); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 687020a9c..e84d3ca1b 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -48,7 +48,7 @@ #define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync #define NUM_FT8_SYMBOLS 79 #define NUM_FT4_SYMBOLS 105 -#define NUM_FST240_SYMBOLS 160 //240/2 data + 5*8 sync +#define NUM_FST4_SYMBOLS 160 //240/2 data + 5*8 sync #define NUM_CW_SYMBOLS 250 #define TX_SAMPLE_RATE 48000 #define NRING 3456000 @@ -203,8 +203,8 @@ private slots: void on_actionJT4_triggered(); void on_actionFT4_triggered(); void on_actionFT8_triggered(); - void on_actionFST240_triggered(); - void on_actionFST240W_triggered(); + void on_actionFST4_triggered(); + void on_actionFST4W_triggered(); void on_TxFreqSpinBox_valueChanged(int arg1); void on_actionSave_decoded_triggered(); void on_actionQuickDecode_toggled (bool); @@ -296,7 +296,7 @@ private slots: void on_actionErase_reference_spectrum_triggered(); void on_actionMeasure_phase_response_triggered(); void on_sbTR_valueChanged (int); - void on_sbTR_FST240W_valueChanged (int); + void on_sbTR_FST4W_valueChanged (int); void on_sbFtol_valueChanged (int); void on_cbFast9_clicked(bool b); void on_sbCQTxFreq_valueChanged(int n); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index cfff2fad3..7dd9f4ab2 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2148,7 +2148,7 @@ list. The list can be maintained in Settings (F2). - + Qt::AlignCenter @@ -2992,8 +2992,8 @@ QLabel[oob="true"] { Mode - - + + @@ -3610,12 +3610,12 @@ QLabel[oob="true"] { FT4 - + true - FST240 + FST4 @@ -3623,15 +3623,15 @@ QLabel[oob="true"] { FT240W - + true - FST240W + FST4W - + true @@ -3639,7 +3639,7 @@ QLabel[oob="true"] { true - Also FST240W + Also FST4W diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 56ed25daf..fb65bd775 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -413,7 +413,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() float bw=9.0*12000.0/m_nsps; //JT9 if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 - if(m_mode.startsWith("FST240")) { + if(m_mode.startsWith("FST4")) { int h=int(pow(2.0,m_nSubMode)); int nsps=800; if(m_TRperiod==30) nsps=1680; @@ -483,7 +483,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,26,x2,26); } - if(m_mode=="FST240W") { + if(m_mode=="FST4W") { x1=XfromFreq(2600); x2=XfromFreq(2700); painter0.drawLine(x1,26,x2,26); @@ -502,7 +502,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() int yRxBottom=yTxTop + 2*yh + 4; if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4" - or m_mode.startsWith("FST240")) { + or m_mode.startsWith("FST4")) { if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) { painter0.setPen(penGreen); @@ -533,7 +533,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() painter0.drawLine(x1,yRxBottom-yh,x1,yRxBottom); painter0.drawLine(x1,yRxBottom,x2,yRxBottom); painter0.drawLine(x2,yRxBottom-yh,x2,yRxBottom); - if(m_mode.startsWith("FST240")) { + if(m_mode.startsWith("FST4")) { x1=XfromFreq(m_rxFreq-m_tol); x2=XfromFreq(m_rxFreq+m_tol); painter0.drawLine(x1,26,x2,26); // Mark the Tol range @@ -543,7 +543,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8" - or m_mode=="FT4" or m_mode.startsWith("FST240")) { + or m_mode=="FT4" or m_mode.startsWith("FST4")) { painter0.setPen(penRed); x1=XfromFreq(m_txFreq); x2=XfromFreq(m_txFreq+bw); @@ -699,7 +699,7 @@ int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq void CPlotter::mouseReleaseEvent (QMouseEvent * event) { - if (Qt::LeftButton == event->button () and m_mode!="FST240W") { + if (Qt::LeftButton == event->button () and m_mode!="FST4W") { int x=event->x(); if(x<0) x=0; if(x>m_Size.width()) x=m_Size.width(); diff --git a/widgets/widegraph.cpp b/widgets/widegraph.cpp index 9e7f6667d..c29d84989 100644 --- a/widgets/widegraph.cpp +++ b/widgets/widegraph.cpp @@ -294,7 +294,7 @@ void WideGraph::setTxFreq(int n) //setTxFreq void WideGraph::setMode(QString mode) //setMode { m_mode=mode; - ui->fSplitSpinBox->setEnabled(m_mode=="JT9+JT65" or m_mode.startsWith("FST240")); + ui->fSplitSpinBox->setEnabled(m_mode=="JT9+JT65" or m_mode.startsWith("FST4")); ui->widePlot->setMode(mode); ui->widePlot->DrawOverlay(); ui->widePlot->update(); @@ -368,7 +368,7 @@ void WideGraph::setRxBand (QString const& band) else { ui->fSplitSpinBox->setValue (m_fMinPerBand.value (band, 2500).toUInt ()); - ui->fSplitSpinBox->setEnabled (m_mode=="JT9+JT65" or m_mode.startsWith("FST240")); + ui->fSplitSpinBox->setEnabled (m_mode=="JT9+JT65" or m_mode.startsWith("FST4")); } ui->widePlot->setRxBand(band); setRxRange (); From c88445ee7b39a213c176da1ad0729040eb8927ff Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 23 Jul 2020 12:53:49 -0500 Subject: [PATCH 216/239] One more 240->4 change in jt9,f90. --- lib/jt9.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 43af4673b..9cfaa9dc7 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -54,8 +54,8 @@ program jt9 option ('jt4', .false., '4', 'JT4 mode', ''), & option ('ft4', .false., '5', 'FT4 mode', ''), & option ('jt65', .false.,'6', 'JT65 mode', ''), & - option ('fst240', .false., '7', 'FST240 mode', ''), & - option ('fst240w', .false., 'W', 'FST240W mode', ''), & + option ('fst4', .false., '7', 'FST4 mode', ''), & + option ('fst4w', .false., 'W', 'FST4W mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), & From a7223a5efa3b5253e1664a76950f2f6407e31f07 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Thu, 23 Jul 2020 19:13:05 +0100 Subject: [PATCH 217/239] A few more cosmetic 240 -> 4 changes --- lib/decoder.f90 | 8 ++++---- lib/fst4/genfst4.f90 | 2 +- lib/fst4_decode.f90 | 2 +- lib/ft8/foxgen.f90 | 2 +- lib/ft8/foxgen_wrap.f90 | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 49e8681f3..a3269aef9 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -188,7 +188,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) endif if(params%nmode.eq.240) then -! We're in FST240 mode +! We're in FST4 mode ndepth=iand(params%ndepth,3) iwspr=0 if(iand(params%ndepth,128).ne.0) iwspr=2 @@ -203,7 +203,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) endif if(params%nmode.eq.241) then -! We're in FST240W mode +! We're in FST4W mode ndepth=iand(params%ndepth,3) iwspr=1 call timer('dec240 ',0) @@ -732,12 +732,12 @@ contains write(line,1001) nutc,nsnr,dt,nint(freq),decoded0,annot 1001 format(i6.6,i4,f5.1,i5,' ` ',1x,a37,1x,a2) write(13,1002) nutc,nint(sync),nsnr,dt,freq,0,decoded0 -1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') +1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FST4') else write(line,1003) nutc,nsnr,dt,nint(freq),decoded0,annot 1003 format(i4.4,i4,f5.1,i5,' ` ',1x,a37,1x,a2,2f7.3) write(13,1004) nutc,nint(sync),nsnr,dt,freq,0,decoded0 -1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST240') +1004 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a37,' FST4') endif if(fmid.ne.-999.0) then diff --git a/lib/fst4/genfst4.f90 b/lib/fst4/genfst4.f90 index 818feee43..650062a03 100644 --- a/lib/fst4/genfst4.f90 +++ b/lib/fst4/genfst4.f90 @@ -5,7 +5,7 @@ subroutine genfst4(msg0,ichk,msgsent,msgbits,i4tone,iwspr) ! - ichk if ichk=1, return only msgsent ! - msgsent message as it will be decoded ! - i4tone array of audio tone values, {0,1,2,3} -! - iwspr in: 0: FST240 1: FST240W +! - iwspr in: 0: FST4 1: FST4W ! out 0: (240,101)/crc24, 1: (240,74)/crc24 ! ! Frame structure: diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 37ab333a1..9626c7114 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -583,7 +583,7 @@ contains subroutine sync_fst4(cd0,i0,f0,hmod,ncoh,np,nss,ntr,fs,sync) -! Compute sync power for a complex, downsampled FST240 signal. +! Compute sync power for a complex, downsampled FST4 signal. use timer_module, only: timer include 'fst4/fst4_params.f90' diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 13299da89..a2899e526 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -15,7 +15,7 @@ subroutine foxgen() ! common block. parameter (NN=79,ND=58,NSPS=4*1920) - parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST240-1800 at 48kHz) + parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz) parameter (NFFT=614400,NH=NFFT/2) character*40 cmsg character*37 msg,msgsent diff --git a/lib/ft8/foxgen_wrap.f90 b/lib/ft8/foxgen_wrap.f90 index eb489cccc..fec9f37c6 100644 --- a/lib/ft8/foxgen_wrap.f90 +++ b/lib/ft8/foxgen_wrap.f90 @@ -1,7 +1,7 @@ subroutine foxgen_wrap(msg40,msgbits,itone) parameter (NN=79,ND=58,KK=77,NSPS=4*1920) - parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST240-1800) + parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST4-1800) character*40 msg40,cmsg character*12 mycall12 From 5eec869b2c869df02e0a723d725b2dc4aa3c3673 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 23 Jul 2020 13:22:12 -0500 Subject: [PATCH 218/239] Remove an unused file. --- lib/fst4/genfst240_64.f90 | 108 -------------------------------------- 1 file changed, 108 deletions(-) delete mode 100644 lib/fst4/genfst240_64.f90 diff --git a/lib/fst4/genfst240_64.f90 b/lib/fst4/genfst240_64.f90 deleted file mode 100644 index 378f8a035..000000000 --- a/lib/fst4/genfst240_64.f90 +++ /dev/null @@ -1,108 +0,0 @@ -subroutine genfst240_64(msg0,ichk,msgsent,msgbits,i4tone,iwspr) - -! Input: -! - msg0 requested message to be transmitted -! - ichk if ichk=1, return only msgsent -! - msgsent message as it will be decoded -! - i4tone array of audio tone values, {0,1,2,3} -! - iwspr 0: (240,101)/crc24, 1: (240,74)/crc24 -! -! Frame structure: -! s8 d30 s8 d30 s8 d30 s8 d30 s8 - - use packjt77 - include 'fst240_params.f90' - character*37 msg0 - character*37 message !Message to be generated - character*37 msgsent !Message as it will be received - character*77 c77 - character*24 c24 - integer*4 i4tone(NN),itmp(ND) - integer*1 codeword(2*ND) - integer*1 msgbits(101),rvec(77) - integer isyncword1(8),isyncword2(8) - integer ncrc24 - integer graymap64(64) - logical unpk77_success - data isyncword1/3,1,4,0,6,5,2/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 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/ - data graymap64/ 0, 1, 3, 2, 6, 7, 5, 4,12,13,15,14,10,11, 9, 8, & - 24,25,27,26,30,31,29,28,20,21,23,22,18,19,17,16, & - 48,49,51,50,54,55,53,52,60,61,63,62,58,59,57,56, & - 40,41,43,42,46,47,45,44,36,37,39,38,34,35,33,32/ - message=msg0 - - do i=1, 37 - if(ichar(message(i:i)).eq.0) then - message(i:37)=' ' - exit - endif - enddo - do i=1,37 !Strip leading blanks - if(message(1:1).ne.' ') exit - message=message(i+1:) - enddo - - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent - msgbits=0 - iwspr=0 - if(i3.eq.0.and.n3.eq.6) then - iwspr=1 - read(c77,'(50i1)') msgbits(1:50) - call get_crc24(msgbits,74,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(51:74) - else - read(c77,'(77i1)') msgbits(1:77) - msgbits(1:77)=mod(msgbits(1:77)+rvec,2) - call get_crc24(msgbits,101,ncrc24) - write(c24,'(b24.24)') ncrc24 - read(c24,'(24i1)') msgbits(78:101) - endif - - if(ichk.eq.1) go to 999 - if(unpk77_success) go to 2 -1 msgbits=0 - itone=0 - msgsent='*** bad message *** ' - go to 999 - - entry get_fst240_tones_from_bits(msgbits,i4tone,iwspr) - -2 continue - if(iwspr.eq.0) then - call encode240_101(msgbits,codeword) - else - call encode240_74(msgbits(1:74),codeword) - endif - -! Grayscale mapping: -! bits tone - - do i=1,40 - is=codeword(2*i)+2*codeword(2*i-1) - if(is.le.1) itmp(i)=is - if(is.eq.2) itmp(i)=3 - if(is.eq.3) itmp(i)=2 - enddo - - i4tone( 1: 8)=isyncword1 - i4tone( 9: 38)=itmp( 1: 30) - i4tone( 39: 46)=isyncword2 - i4tone( 47: 76)=itmp( 31: 60) - i4tone( 77: 84)=isyncword1 - i4tone( 85:114)=itmp( 61: 90) - i4tone(115:122)=isyncword2 - i4tone(123:152)=itmp( 91:120) - i4tone(153:160)=isyncword1 - -999 return - -end subroutine genfst240_64 - -subroutine graycode(in From 19d24789aae4c6eaa5d3f0f61f5dea98888e2c06 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 24 Jul 2020 12:43:35 +0100 Subject: [PATCH 219/239] Revert "Change band name 2190m to 2200m." This reverts commit fe86a6562cd84ea4933a636d7022a6d66d85c77a. --- models/Bands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/Bands.cpp b/models/Bands.cpp index aa21eae9e..832c36185 100644 --- a/models/Bands.cpp +++ b/models/Bands.cpp @@ -15,7 +15,7 @@ namespace Radio::Frequency lower_bound_; Radio::Frequency upper_bound_; } constexpr ADIF_bands[] = { - {"2200m", 136000u, 137000u}, + {"2190m", 136000u, 137000u}, {"630m", 472000u, 479000u}, {"560m", 501000u, 504000u}, {"160m", 1800000u, 2000000u}, From 29fc0ced19226667fdff4d7782468824dfa58c87 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 24 Jul 2020 12:46:43 +0100 Subject: [PATCH 220/239] Revert "Fix double-clicking on a decode line containing fSpread." Change superseded. This reverts commit d9c2a1182111d20f8084def9816055267d8ccdc0. --- widgets/mainwindow.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 64a80259e..074576648 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4518,9 +4518,7 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers) } return; } - QString t{cursor.block().text().trimmed().left(61).remove("TU; ")}; - t=t.left(46)+" "+t.mid(51); - DecodedText message{t.trimmed()}; + DecodedText message {cursor.block().text().trimmed().left(61).remove("TU; ")}; m_bDoubleClicked = true; processMessage (message, modifiers); } From c802c60afa49f4a23a43745c365762b557a7aa88 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 24 Jul 2020 10:58:10 -0400 Subject: [PATCH 221/239] Allow FST4 to use Split (Rig or Fake it). Set Tx upper freq limit for FST4W to 1600 Hz. --- widgets/mainwindow.cpp | 3 ++- widgets/mainwindow.ui | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 64a80259e..ade829eff 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -6989,7 +6989,8 @@ void MainWindow::setXIT(int n, Frequency base) m_XIT = 0; if (!m_bSimplex) { // m_bSimplex is false, so we can use split mode if requested - if (m_config.split_mode () && (!m_config.enable_VHF_features () || m_mode == "FT8")) { + if (m_config.split_mode () && (!m_config.enable_VHF_features () || m_mode == "FT8" || + m_mode=="FST4")) { // Don't use XIT for VHF & up m_XIT=(n/500)*500 - 1500; } diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 7dd9f4ab2..c777609b0 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2121,7 +2121,7 @@ list. The list can be maintained in Settings (F2). 1400 - 1700 + 1600 1500 From dbaffea0cdbabdf7eb0a902dc0189f3656378155 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 24 Jul 2020 11:13:48 -0400 Subject: [PATCH 222/239] Allow only TR periods >= 120 s for FST4W. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ade829eff..d7be5cc6c 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -428,7 +428,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300, 900, 1800}); - ui->sbTR_FST4W->values ({15, 30, 60, 120, 300, 900, 1800}); + ui->sbTR_FST4W->values ({120, 300, 900, 1800}); ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser2->set_configuration (&m_config); From 5c4878a00a4f544cbc33cc09d97d9964d9ba750e Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Fri, 24 Jul 2020 13:35:04 -0400 Subject: [PATCH 223/239] Display cursor position on Wide graph as a ToolTip. --- widgets/plotter.cpp | 8 ++++++++ widgets/plotter.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index fb65bd775..c21d7e5f0 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -56,6 +56,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_NoSystemBackground, true); + setMouseTracking(true); m_bReplot=false; // contextual pop up menu @@ -697,6 +698,13 @@ void CPlotter::setRxFreq (int x) //setRxFreq int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq +void CPlotter::mouseMoveEvent (QMouseEvent * event) +{ + int x=event->x(); + QToolTip::showText(event->globalPos(),QString::number(int(FreqfromX(x)))); + QWidget::mouseMoveEvent(event); +} + void CPlotter::mouseReleaseEvent (QMouseEvent * event) { if (Qt::LeftButton == event->button () and m_mode!="FST4W") { diff --git a/widgets/plotter.h b/widgets/plotter.h index b3eb85855..b4b4cf42b 100644 --- a/widgets/plotter.h +++ b/widgets/plotter.h @@ -13,6 +13,7 @@ #include #include #include +#include #define VERT_DIVS 7 //specify grid screen divisions #define HORZ_DIVS 20 @@ -91,6 +92,7 @@ protected: //re-implemented widget event handlers void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent* event) override; + void mouseMoveEvent(QMouseEvent * event) override; void mouseReleaseEvent (QMouseEvent * event) override; void mouseDoubleClickEvent (QMouseEvent * event) override; From ceeafa5bedf3746e3db4440da1b2bb1347a8ce37 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sat, 25 Jul 2020 16:02:42 -0400 Subject: [PATCH 224/239] *** TEMPORARY *** Add a feature to transmit FT8 and FST4 at the same time. --- widgets/mainwindow.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index d7be5cc6c..a2dc97dcc 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3837,7 +3837,11 @@ void MainWindow::guiUpdate() m_modulator->set_nsym(nsym); } } - if(m_modeTx=="FT8") { + + QString t = QString::fromStdString(message).trimmed(); + bool both=(t=="CQ BOTH K1JT FN20" or t=="CQ BOTH K9AN EN50"); + + if(m_modeTx=="FT8" or both) { if(SpecOp::FOX==m_config.special_op_id() and ui->tabWidget->currentIndex()==2) { foxTxSequencer(); } else { @@ -3855,7 +3859,6 @@ void MainWindow::guiUpdate() int nwave=nsym*nsps; gen_ft8wave_(const_cast(itone),&nsym,&nsps,&bt,&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(); @@ -3911,8 +3914,20 @@ void MainWindow::guiUpdate() float f0=ui->TxFreqSpinBox->value() - m_XIT + 1.5*dfreq; int nwave=(nsym+2)*nsps; int icmplx=0; + + float wave_both[15*48000]; + if(both) { + memcpy(wave_both,foxcom_.wave,4*15*48000); //Copy the FT8 wave[] into wave_both[] + f0 += 200; + } gen_fst4wave_(const_cast(itone),&nsym,&nsps,&nwave, &fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave); + if(both) { + for(int i=0; i<15*48000; i++) { + foxcom_.wave[i]=0.5*(wave_both[i] + foxcom_.wave[i]); + } + } + } if(SpecOp::EU_VHF==m_config.special_op_id()) { From 7566f3548df8fcd647196c5247f11b372e9c2163 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sun, 26 Jul 2020 02:58:04 +0100 Subject: [PATCH 225/239] Post FST4W spots to WSPRNet.org Includes a re-factoring of the WSPRNet class, particularly to handle direct spot posts as well as via a file from wsprd. Switched from GET http request method to POST method. FST4W spots post the same information a WSPR spots except the drift field is always zero (FST4W has no drift compensation, so no drift figure is calculated by the decoder), and the mode field reflects the T/R period in minutes. This means FST4W-120A will be similar to WSPR-2, an FST4W-900 will be similar to WSPR-15. I don't see any way to view the mode field on either the new or old database format queries on WSPRnet, so it is hard to tell if that field is actually stored. --- Network/wsprnet.cpp | 445 +++++++++++++++++++++++++---------------- Network/wsprnet.h | 57 ++++-- widgets/mainwindow.cpp | 68 ++++--- widgets/mainwindow.h | 4 +- 4 files changed, 354 insertions(+), 220 deletions(-) diff --git a/Network/wsprnet.cpp b/Network/wsprnet.cpp index cdfed7683..669ab1554 100644 --- a/Network/wsprnet.cpp +++ b/Network/wsprnet.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include @@ -18,215 +20,314 @@ namespace { - char const * const wsprNetUrl = "http://wsprnet.org/post?"; - // char const * const wsprNetUrl = "http://127.0.0.1/post?"; + char const * const wsprNetUrl = "http://wsprnet.org/post/"; + //char const * const wsprNetUrl = "http://127.0.0.1:5000/post/"; + + // + // tested with this python REST mock of WSPRNet.org + // + /* +# Mock WSPRNet.org RESTful API +from flask import Flask, request, url_for +from flask_restful import Resource, Api + +app = Flask(__name__) + +@app.route ('/post/', methods=['GET', 'POST']) +def spot (): + if request.method == 'POST': + print (request.form) + return "1 spot(s) added" + +with app.test_request_context (): + print (url_for ('spot')) + */ + + // regexp to parse FST4W decodes + QRegularExpression fst4_re {R"( + (?