diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f7d8072f..6c15494c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -937,6 +937,9 @@ add_executable (wsprsim ${wsprsim_CSRCS}) add_executable (jt4code lib/jt4code.f90 wsjtx.rc) target_link_libraries (jt4code wsjt_fort wsjt_cxx) +add_executable (jt65 lib/jt65.f90 ${jt65_CXXSRCS} wsjtx.rc) +target_link_libraries (jt65 wsjt_fort wsjt_cxx ${FFTW3_LIBRARIES}) + add_executable (jt9 lib/jt9.f90 lib/jt9a.f90 lib/jt9b.f90 lib/jt9c.f90 ${jt9_CXXSRCS} wsjtx.rc) if (${OPENMP_FOUND} OR APPLE) if (APPLE) diff --git a/lib/jt65.f90 b/lib/jt65.f90 index 93410d0df..0097fad28 100644 --- a/lib/jt65.f90 +++ b/lib/jt65.f90 @@ -4,7 +4,7 @@ program jt65 use options character c -logical :: display_help=.false.,err + logical :: display_help=.false. parameter (NZMAX=60*12000) integer*4 ihdr(11) integer*2 id2(NZMAX) @@ -14,11 +14,11 @@ logical :: display_help=.false.,err common/tracer/limtrace,lu equivalence (lenfile,ihdr(2)) type (option) :: long_options(5) = [ & - option ('freq',.true.,'n','default=1270',''), & - option ('help',.false.,'h','Display this help message',''), & - option ('ntrials',.true.,'n','default=1000',''), & - option ('robust sync',.false.,'n','default: disabled',''), & - option ('single-signal mode',.false.,'s','default: disabled','') ] + option ('freq',.true.,'f','signal frequency, default FREQ=1270','FREQ'), & + option ('help',.false.,'h','Display this help message',''), & + option ('ntrials',.true.,'n','number of trials, default TRIALS=10000','TRIALS'), & + option ('robust-sync',.false.,'r','robust sync',''), & + option ('single-signal-mode',.false.,'s','decode at signal frequency only','') ] limtrace=0 lu=12 @@ -33,7 +33,7 @@ n2pass=2 nrobust=0 do - call getopt('f:hn:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,err) + call getopt('f:hn:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.) if( nstat .ne. 0 ) then exit end if @@ -53,11 +53,17 @@ nrobust=0 end select end do - nargs=iargc() - if(display_help .or. (nargs.lt.1)) then - print*,'Usage: jt65 [-f freq] [-n ntrials] [-s] file1 [file2 ...]' - print*,' -r robust sync' - print*,' -s single-signal mode' + if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then + print *, '' + print *, 'Usage: jt65 [OPTIONS] file1 [file2 ...]' + print *, '' + print *, ' JT65 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 @@ -65,12 +71,12 @@ nrobust=0 call timer('jt65 ',0) ndecoded=0 - do ifile=1,nargs + do ifile=noffset+1,noffset+nremain newdat=1 nfa=nlow nfb=nhigh - call getarg(ifile+noffset,infile) - if( infile.eq.'' ) goto 900 + call get_command_argument(ifile,optarg,narglen) + infile=optarg(:narglen) open(10,file=infile,access='stream',status='old',err=998) call timer('read ',0) read(10) ihdr @@ -93,7 +99,7 @@ nrobust=0 call timer('jt65a ',1) enddo -900 call timer('jt65 ',1) + call timer('jt65 ',1) call timer('jt65 ',101) ! call four2a(a,-1,1,1,1) !Free the memory used for plans ! call filbig(a,-1,1,0.0,0,0,0,0,0) ! (ditto) diff --git a/lib/jt65sim.f90 b/lib/jt65sim.f90 index 257f7fc04..339b21666 100644 --- a/lib/jt65sim.f90 +++ b/lib/jt65sim.f90 @@ -4,6 +4,7 @@ program jt65sim use wavhdr use packjt + use options parameter (NMAX=54*12000) ! = 648,000 parameter (NFFT=10*65536,NH=NFFT/2) type(hdr) h !Header for .wav file @@ -17,7 +18,19 @@ program jt65sim complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading complex z real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq,sps - character msg*22,arg*8,fname*11,csubmode*1,call1*5,call2*5 + character msg*22,fname*11,csubmode*1,call1*5,call2*5,c,optarg*500,numbuf*32 + logical :: display_help=.false.,seed_prngs=.true. + type (option) :: long_options(8) = [ & + option ('help',.false.,'h','Display this help message',''), & + option ('sub-mode',.true.,'m','sub mode, default MODE=A','MODE'), & + option ('num-sigs',.true.,'n','number of signals per file, default SIGNALS=10','SIGNALS'), & + option ('doppler-spread',.true.,'d','Doppler spread, default SPREAD=0.0','SPREAD'), & + option ('time-offset',.true., & + 't','Time delta, use \ to escape -ve values, default SECONDS=0.0','SECONDS'), & + option ('num-files',.true.,'f','Number of files to generate, default FILES=1','FILES'), & + option ('no-prng-seed',.false.,'p','Do not seed PRNGs (use for reproducible tests)',''), & + option ('strength',.true.,'s', & + 'S/N in dB (2500Hz reference b/w), use 0 for a range, use \ to escape -ve values, default SNR=0','SNR') ] integer nprc(126) !Sync pattern data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, & 0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, & @@ -27,32 +40,75 @@ program jt65sim 0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, & 1,1,1,1,1,1/ - nargs=iargc() - if(nargs.ne.6) then - print*,'Usage: jt65sim mode nsigs fspread SNR DT nfiles' - print*,'Example: jt65sim A 10 0.2 -24.5 0.0 1' - print*,'Enter SNR = 0 to generate a range of SNRs.' + csubmode='A' + mode65=1 + nsigs=10 + fspread=0. + xdt=0. + snrdb=0. + nfiles=1 + + do + call getopt('hm:n:d:t:f:ps:',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 ('m') + read (optarg(:narglen), *) csubmode + if(csubmode.eq.'A') mode65=1 + if(csubmode.eq.'B') mode65=2 + if(csubmode.eq.'C') mode65=4 + case ('n') + read (optarg(:narglen), *,err=10) nsigs + case ('d') + read (optarg(:narglen), *,err=10) fspread + case ('t') + read (optarg(:narglen), *) numbuf + if (numbuf(1:1) == '\') then + read (numbuf(2:), *,err=10) xdt + else + read (numbuf, *,err=10) xdt + end if + case ('f') + read (optarg(:narglen), *,err=10) nfiles + case ('p') + seed_prngs=.false. + case ('s') + read (optarg(:narglen), *) numbuf + if (numbuf(1:1) == '\') then + read (numbuf(2:), *,err=10) snrdb + else + read (numbuf, *,err=10) snrdb + end if + end select + cycle +10 display_help=.true. + print *, 'Optional argument format error for option -', c + end do + + if(display_help .or. nstat.lt.0 .or. nremain.ge.1) then + print *, '' + print *, 'Usage: jt65sim [OPTIONS]' + print *, '' + print *, ' Generate one or more simulated JT65 signals in .WAV file(s)' + print *, '' + print *, 'Example: jt65sim -m B -n 10 -d 0.2 -s \-24.5 -t 0.0 -f 4' + print *, '' + print *, 'OPTIONS:' + print *, '' + do i = 1, size (long_options) + call long_options(i) % print (6) + end do go to 999 endif - call init_random_seed() ! seed Fortran RANDOM_NUMBER generator - call sgran() ! see C rand generator (used in gran) - - csubmode='A' - call getarg(1,csubmode) - mode65=1 - if(csubmode.eq.'B') mode65=2 - if(csubmode.eq.'C') mode65=4 - call getarg(2,arg) - read(arg,*) nsigs !Number of signals in each file - call getarg(3,arg) - read(arg,*) fspread !Doppler spread (Hz) - call getarg(4,arg) - read(arg,*) snrdb !S/N in dB (2500 hz reference BW) - call getarg(5,arg) - read(arg,*) xdt !Generated DT - call getarg(6,arg) - read(arg,*) nfiles !Number of files + if (seed_prngs) then + call init_random_seed() ! seed Fortran RANDOM_NUMBER generator + call sgran() ! see C rand generator (used in gran) + end if rms=100. fsample=12000.d0 !Sample rate (Hz) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 2316b0530..d50c80294 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -18,36 +18,39 @@ program jt9 character wisfile*80 integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, & fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=60001 - logical :: shmem = .false., read_files = .false., have_args = .false., & + logical :: shmem = .false., read_files = .false., & tx9 = .false., display_help = .false. type (option) :: long_options(17) = [ & option ('help', .false., 'h', 'Display this help message', ''), & - option ('shmem',.true.,'s','Use shared memory for sample data',''), & - option ('tr-period', .true., 'p', 'Tx/Rx period, default=1', ''), & - option ('executable-path', .true., 'e', & - 'Location of subordinate executables (KVASD) default="."', ''), & - option ('data-path', .true., 'a', & - 'Location of writeable data files, default="."', ''), & - option ('temp-path', .true., 't', 'Temporary files path, default="."', & - ''), & - option ('lowest', .true., 'L', & - 'Lowest frequency decoded (JT65), default=200Hz', ''), & - option ('highest', .true., 'H', & - 'Highest frequency decoded, default=4007Hz', ''), & - option ('split', .true., 'S', & - 'Lowest JT9 frequency decoded, default=2700Hz', ''), & - option ('rx-frequency', .true., 'f', & - 'Receive frequency offset, default=1500', ''), & - option ('patience', .true., 'w', & - 'FFTW3 planing patience (0-4), default=1', ''), & - option ('fft-threads', .true., 'm', & - 'Number of threads to process large FFTs, default=1', ''), & - option ('jt65', .false., '6', 'JT65 mode', ''), & - option ('jt9', .false., '9', 'JT9 mode', ''), & - option ('jt4', .false., '4', 'JT4 mode', ''), & - option ('depth', .true., 'd', 'JT9 decoding depth (1-3), default=1', & - ''), & - option ('tx-jt9', .false., 'T', 'Tx mode is JT9, default=JT65', '') ] + option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & + option ('tr-period', .true., 'p', 'Tx/Rx period, default MINUTES=1', & + 'MINUTES'), & + option ('executable-path', .true., 'e', & + 'Location of subordinate executables (KVASD) default PATH="."', & + 'PATH'), & + option ('data-path', .true., 'a', & + 'Location of writeable data files, default PATH="."', 'PATH'), & + option ('temp-path', .true., 't', & + 'Temporary files path, default PATH="."', 'PATH'), & + option ('lowest', .true., 'L', & + 'Lowest frequency decoded (JT65), default HERTZ=200', 'HERTZ'), & + option ('highest', .true., 'H', & + 'Highest frequency decoded, default HERTZ=4007', 'HERTZ'), & + option ('split', .true., 'S', & + 'Lowest JT9 frequency decoded, default HERTZ=2700', 'HERTZ'), & + option ('rx-frequency', .true., 'f', & + 'Receive frequency offset, default HERTZ=1500', 'HERTZ'), & + option ('patience', .true., 'w', & + 'FFTW3 planing patience (0-4), default PATIENCE=1', 'PATIENCE'), & + option ('fft-threads', .true., 'm', & + 'Number of threads to process large FFTs, default THREADS=1', & + 'THREADS'), & + option ('jt65', .false., '6', 'JT65 mode', ''), & + option ('jt9', .false., '9', 'JT9 mode', ''), & + option ('jt4', .false., '4', 'JT4 mode', ''), & + option ('depth', .true., 'd', & + 'JT9 decoding depth (1-3), default DEPTH=1', 'DEPTH'), & + option ('tx-jt9', .false., 'T', 'Tx mode is JT9', '') ] character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6 common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, & @@ -63,11 +66,10 @@ program jt9 do call getopt('hs:e:a:r:m:p:d:f:w:t:964TL:S:H:',long_options,c, & - optarg,arglen,stat,offset,remain) + optarg,arglen,stat,offset,remain,.true.) if (stat .ne. 0) then exit end if - have_args = .true. select case (c) case ('h') display_help = .true. @@ -117,19 +119,20 @@ program jt9 end select end do - if (display_help .or. .not. have_args .or. & - (stat .lt. 0 .or. (shmem .and. remain .gt. 0) & - .or. (read_files .and. remain .eq. 0) .or. & - (shmem .and. read_files))) then - - print*,'Usage: jt9 -p OPTIONS file1 [file2 ...]' - print*,' Reads data from *.wav files.' - print*,'' - print*,' jt9 -s [-w n] [-m n] [-e path] [-a path] [-t path]' - print*,' Gets data from shared memory region with key==' + if (display_help .or. stat .lt. 0 & + .or. (shmem .and. remain .gt. 0) & + .or. (read_files .and. remain .lt. 1) & + .or. (shmem .and. read_files)) then + print *, 'Usage: jt9 [OPTIONS] file1 [file2 ...]' + print *, ' Reads data from *.wav files.' + print *, '' + print *, ' jt9 -s [-w patience] [-m threads] [-e path] [-a path] [-t path]' + print *, ' Gets data from shared memory region with key==' + print *, '' + print *, 'OPTIONS:' + print *, '' do i = 1, size (long_options) - print*,'' call long_options(i) % print (6) end do go to 999