diff --git a/CMakeLists.txt b/CMakeLists.txt index da9fe16d9..c7a28fdb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ set (wsjt_FSRCS lib/gen9.f90 lib/geniscat.f90 lib/genmsk.f90 + lib/genmsk144.f90 lib/genmsk_short.f90 lib/genwspr.f90 lib/geodist.f90 @@ -384,6 +385,7 @@ set (wsjt_FSRCS lib/jt9_decode.f90 lib/jt9fano.f90 lib/JTMSKsim.f90 + lib/msk144sim.f90 lib/jtmsk_decode.f90 lib/jtmsk_short.f90 lib/ldpcsim.f90 @@ -396,6 +398,8 @@ set (wsjt_FSRCS lib/morse.f90 lib/move.f90 lib/mskdt.f90 + lib/msk144d.f90 + lib/msk144_decode.f90 lib/options.f90 lib/packjt.f90 lib/pctile.f90 @@ -435,6 +439,7 @@ set (wsjt_FSRCS lib/sync9w.f90 lib/synciscat.f90 lib/syncmsk.f90 + lib/syncmsk144.f90 lib/timer_C_wrapper.f90 lib/timer_impl.f90 lib/timer_module.f90 @@ -1023,6 +1028,12 @@ target_link_libraries (ldpcsim wsjt_fort wsjt_cxx) add_executable (JTMSKsim lib/JTMSKsim.f90 wsjtx.rc) target_link_libraries (JTMSKsim wsjt_fort wsjt_cxx) +add_executable (msk144sim lib/msk144sim.f90 wsjtx.rc) +target_link_libraries (msk144sim wsjt_fort wsjt_cxx) + +add_executable (msk144d lib/msk144d.f90 wsjtx.rc) +target_link_libraries (msk144d wsjt_fort wsjt_cxx) + add_executable (jt9 ${jt9_FSRCS} ${jt9_CXXSRCS} wsjtx.rc) if (${OPENMP_FOUND} OR APPLE) if (APPLE) diff --git a/lib/genmsk144.f90 b/lib/genmsk144.f90 index 282bdc041..43f8c7002 100644 --- a/lib/genmsk144.f90 +++ b/lib/genmsk144.f90 @@ -160,6 +160,6 @@ subroutine genmsk144(msg0,ichk,msgsent,i4tone,itype) ! Flip polarity i4tone=-i4tone+1 - + 999 return end subroutine genmsk144 diff --git a/lib/msk144d.f90 b/lib/msk144d.f90 new file mode 100644 index 000000000..c1d701d62 --- /dev/null +++ b/lib/msk144d.f90 @@ -0,0 +1,77 @@ +program msk144d + + ! Test the msk144 decoder for WSJT-X + + use options + use timer_module, only: timer + use timer_impl, only: init_timer + use readwav + + character c,mode + character*80 line(100) + logical :: display_help=.false. + type(wav_header) :: wav + integer*2 id2(15*12000) + integer narg(0:14) + character*80 infile + character(len=500) optarg + + type (option) :: long_options(2) = [ & + option ('help',.false.,'h','Display this help message',''), & + option ('ntrials',.true.,'n','number of trials, default TRIALS=10000','TRIALS') & + ] + do + call getopt('hn:',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.) + if( nstat .ne. 0 ) then + exit + end if + select case (c) + case ('h') + display_help = .true. + case ('n') + read (optarg(:narglen), *) ntrials + end select + end do + + if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then + print *, '' + print *, 'Usage: msk144d [OPTIONS] file1 [file2 ...]' + print *, '' + print *, ' msk144 decode pre-recorded .WAV file(s)' + print *, '' + print *, 'OPTIONS:' + print *, '' + do i = 1, size (long_options) + call long_options(i) % print (6) + end do + go to 999 + endif + + call init_timer ('timer.out') + call timer('jt65 ',0) + + ndecoded=0 + do ifile=noffset+1,noffset+nremain + call get_command_argument(ifile,optarg,narglen) + infile=optarg(:narglen) + call timer('read ',0) + call wav%read (infile) + i1=index(infile,'.wav') + if( i1 .eq. 0 ) i1=index(infile,'.WAV') + read(infile(i1-4:i1-1),*,err=998) nutc + npts=15*12000 + read(unit=wav%lun) id2(1:npts) + close(unit=wav%lun) + call timer('read ',1) + call msk144_decode(id2,npts,nutc,line) + enddo + + call timer('msk144 ',1) + call timer('msk144 ',101) + go to 999 + +998 print*,'Cannot read from file:' + print*,infile + +999 continue +end program msk144d diff --git a/lib/JTMSKsim144.f90 b/lib/msk144sim.f90 similarity index 88% rename from lib/JTMSKsim144.f90 rename to lib/msk144sim.f90 index 2fc0735ee..3aeb1b942 100644 --- a/lib/JTMSKsim144.f90 +++ b/lib/msk144sim.f90 @@ -1,4 +1,4 @@ -program JTMSKsim +program msk144sim use wavhdr parameter (NMAX=15*12000) @@ -17,10 +17,9 @@ program JTMSKsim nargs=iargc() if(nargs.ne.5) then - print*,'Usage: JTMSKsim message freq width snr nfiles' + print*,'Usage: msk144sim message freq width snr nfiles' print*,' ' - print*,'Examples: JTMSKsim "K1ABC W9XYZ EN37" 1500 0.12 2 1' - print*,' JTMSKsim " R26" 1500 0.01 1 3' + print*,'Example: msk144sim "K1ABC W9XYZ EN37" 1500 0.12 2 1' go to 999 endif call getarg(1,msg) @@ -86,4 +85,4 @@ program JTMSKsim enddo -999 end program JTMSKsim +999 end program msk144sim diff --git a/lib/syncmsk144.f90 b/lib/syncmsk144.f90 index 42f1759f1..68cc91941 100644 --- a/lib/syncmsk144.f90 +++ b/lib/syncmsk144.f90 @@ -1,7 +1,4 @@ -subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) - -! Attempt synchronization, and if successful decode using Viterbi algorithm. - +subroutine syncmsk144(cdat,npts,metric,msgreceived,fest) use iso_c_binding, only: c_loc,c_size_t use packjt use hashing @@ -43,13 +40,11 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) data s8/0,1,1,1,0,0,1,0/ save first,cb,cd,pi,twopi,dt,f0,f1 - open(unit=78,file="/Users/sfranke/Builds/wsjtx_install/sfdebug.txt") if(first) then - write(78,*) "Initializing ldpc." - pchk_file="/Users/sfranke/Builds/wsjtx_install/peg-128-80-reg3.pchk" - gen_file="/Users/sfranke/Builds/wsjtx_install/peg-128-80-reg3.gen" +! These files can be found in /lib/ldpc/jtmode_codes directory + pchk_file="peg-128-80-reg3.pchk" + gen_file="peg-128-80-reg3.gen" call init_ldpc(trim(pchk_file)//char(0),trim(gen_file)//char(0)) - write(78,*) "after init_ldpc" ! define half-sine pulse and raised-cosine edge window pi=4d0*datan(1d0) twopi=8d0*datan(1d0) @@ -75,7 +70,6 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) first=.false. endif - ! Coarse carrier frequency sync ! look for tones near 2k and 4k in the analytic signal spectrum ! search range for coarse frequency error is +/- 100 Hz @@ -89,6 +83,7 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) ctmp(npts-11:npts)=ctmp(npts-11:npts)*rcw(12:1:-1) call four2a(ctmp,nfft,1,-1,1) tonespec=abs(ctmp)**2 + ismask=.false. ismask(1901:2101)=.true. ! high tone search window iloc=maxloc(tonespec,ismask) @@ -110,9 +105,9 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) endif fdiff=(ihpk-ilpk)*df -! write(78,*) "Coarse frequency error: ",ferr -! write(78,*) "Tone / avg : ",q1 -! write(78,*) "Tone separation : ",fdiff + write(78,*) "Coarse frequency error: ",ferr + write(78,*) "Tone / avg : ",q1 + write(78,*) "Tone separation : ",fdiff ! remove coarse freq error - should now be within a few Hz call tweak1(cdat,npts,-(1500+ferr),cdat) @@ -133,7 +128,7 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) iloc=maxloc(dd) ic2=iloc(1) -! write(78,*) "Syncs: ic1,ic2 ",ic1,ic2 + write(78,*) "Syncs: ic1,ic2 ",ic1,ic2 ic=ic2 ! do i=1,npts-448-41 @@ -145,8 +140,8 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) phase0=atan2(imag(cca+ccb),real(cca+ccb)) cfac=ccb*conjg(cca) ferr2=atan2(imag(cfac),real(cfac))/(twopi*56*6*dt) - write(78,*) "Fine frequency error: ",ferr2 - write(78,*) "Coarse Carrier phase : ",phase0 + write(78,*) "Fine frequency error: ",ferr2 + write(78,*) "Coarse Carrier phase : ",phase0 fest=1500+ferr+ferr2 write(78,*) "Estimated f0 : ",fest @@ -182,8 +177,12 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) hardbits(i)=1 endif enddo -! write(78,*) hardbits(1:8) -! write(78,*) hardbits(57:57+7) + +! calculated the number of sync-word bits that are incorrect + nbadsync=sum(s8*(2*hardbits(1:8)-1)) + nbadsync=nbadsync+sum(s8*(2*hardbits(57:57+7)-1)) + nbadsync=16-nbadsync + write(78,*) nbadsync," bad sync bits" hardword(1:48)=hardbits(9:9+47) hardword(49:128)=hardbits(65:65+80-1) @@ -240,7 +239,6 @@ subroutine syncmsk144(cdat,npts,jpk,ipk,idf,rmax,snr,metric,msgreceived,fest) enddo call unpackmsg(i4Dec6BitWords,msgreceived) endif -close(78) return end subroutine syncmsk144