mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2026-06-07 08:24:53 -04:00
Remove JTMSK mode and all related routines. Beware of possible unintended side effects!
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7079 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
@@ -1,123 +0,0 @@
|
||||
program JTMSKcode
|
||||
|
||||
! Generate simulated data for testing of JTMSK
|
||||
|
||||
use iso_c_binding, only: c_loc,c_size_t
|
||||
use hashing
|
||||
use packjt
|
||||
character msg*22,decoded*22,bad*1,msgtype*13
|
||||
integer*4 i4tone(234) !Channel symbols (values 0-1)
|
||||
integer*1 e1(201)
|
||||
integer*1 r1(201)
|
||||
integer*1, target :: d8(13)
|
||||
integer mettab(0:255,0:1) !Metric table for BPSK modulation
|
||||
integer*1 i1hash(4)
|
||||
integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
|
||||
character*72 c72
|
||||
! real*8 twopi,dt,f0,f1,f,phi,dphi
|
||||
real xp(29)
|
||||
equivalence (ihash,i1hash)
|
||||
data xp/0.500000, 0.401241, 0.309897, 0.231832, 0.168095, &
|
||||
0.119704, 0.083523, 0.057387, 0.039215, 0.026890, &
|
||||
0.018084, 0.012184, 0.008196, 0.005475, 0.003808, &
|
||||
0.002481, 0.001710, 0.001052, 0.000789, 0.000469, &
|
||||
0.000329, 0.000225, 0.000187, 0.000086, 0.000063, &
|
||||
0.000017, 0.000091, 0.000032, 0.000045/
|
||||
include 'testmsg.f90'
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.1) then
|
||||
print*,'Usage: JTMSKcode "message"'
|
||||
! print*,' JTMSKcode -t'
|
||||
go to 999
|
||||
endif
|
||||
|
||||
call getarg(1,msg)
|
||||
nmsg=1
|
||||
if(msg(1:2).eq."-t") nmsg=NTEST
|
||||
|
||||
! Get the metric table
|
||||
bias=0.0
|
||||
scale=20.0
|
||||
xln2=log(2.0)
|
||||
do i=128,156
|
||||
x0=log(max(0.0001,2.0*xp(i-127)))/xln2
|
||||
x1=log(max(0.001,2.0*(1.0-xp(i-127))))/xln2
|
||||
mettab(i,0)=nint(scale*(x0-bias))
|
||||
mettab(i,1)=nint(scale*(x1-bias))
|
||||
mettab(256-i,0)=mettab(i,1)
|
||||
mettab(256-i,1)=mettab(i,0)
|
||||
enddo
|
||||
do i=157,255
|
||||
mettab(i,0)=mettab(156,0)
|
||||
mettab(i,1)=mettab(156,1)
|
||||
mettab(256-i,0)=mettab(i,1)
|
||||
mettab(256-i,1)=mettab(i,0)
|
||||
enddo
|
||||
|
||||
write(*,1010)
|
||||
1010 format(" Message Decoded Err? Type"/ &
|
||||
74("-"))
|
||||
do imsg=1,nmsg
|
||||
if(nmsg.gt.1) msg=testmsg(imsg)
|
||||
call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
|
||||
ichk=0
|
||||
call genmsk(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s
|
||||
msgtype=""
|
||||
if(itype.eq.1) msgtype="Std Msg"
|
||||
if(itype.eq.2) msgtype="Type 1 prefix"
|
||||
if(itype.eq.3) msgtype="Type 1 suffix"
|
||||
if(itype.eq.4) msgtype="Type 2 prefix"
|
||||
if(itype.eq.5) msgtype="Type 2 suffix"
|
||||
if(itype.eq.6) msgtype="Free text"
|
||||
|
||||
! Extract the data symbols, skipping over sync and parity bits
|
||||
n1=35
|
||||
n2=69
|
||||
n3=94
|
||||
|
||||
r1(1:n1)=i4tone(11+1:11+n1)
|
||||
r1(n1+1:n1+n2)=i4tone(23+n1+1:23+n1+n2)
|
||||
r1(n1+n2+1:n1+n2+n3)=i4tone(35+n1+n2+1:35+n1+n2+n3)
|
||||
where(r1.eq.0) r1=127
|
||||
where(r1.eq.1) r1=-127
|
||||
|
||||
j=0
|
||||
do i=1,99
|
||||
j=j+1
|
||||
e1(j)=r1(i)
|
||||
j=j+1
|
||||
e1(j)=r1(i+99)
|
||||
enddo
|
||||
|
||||
nb1=87
|
||||
call vit213(e1,nb1,mettab,d8,metric)
|
||||
|
||||
ihash=nhash(c_loc(d8),int(9,c_size_t),146)
|
||||
ihash=2*iand(ihash,32767)
|
||||
decoded=" "
|
||||
if(d8(10).eq.i1hash(2) .and. d8(11).eq.i1hash(1)) then
|
||||
write(c72,1012) d8(1:9)
|
||||
1012 format(9b8.8)
|
||||
read(c72,1014) i4Msg6BitWords
|
||||
1014 format(12b6.6)
|
||||
call unpackmsg(i4Msg6BitWords,decoded) !Unpack to get msgsent
|
||||
endif
|
||||
|
||||
bad=" "
|
||||
if(decoded.ne.msg) bad="*"
|
||||
write(*,1020) imsg,msg,decoded,bad,itype,msgtype
|
||||
1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13)
|
||||
|
||||
enddo
|
||||
|
||||
if(nmsg.eq.1) then
|
||||
open(10,file='JTMSKcode.out',status='unknown')
|
||||
do j=1,234
|
||||
write(10,1030) j,i4tone(j)
|
||||
1030 format(2i5)
|
||||
enddo
|
||||
close(10)
|
||||
endif
|
||||
|
||||
999 end program JTMSKcode
|
||||
@@ -1,120 +0,0 @@
|
||||
program JTMSKfer
|
||||
|
||||
! Measure the frame error rate (fer) of the rate 1/2, K=13 conv. code with
|
||||
! coherent BPSK, Viterbi decoding, perfect sync. The results are to be
|
||||
! compared with LDPC fer's produced by the routines in the ldpc sandbox folder.
|
||||
! These coherent BPSK results will not correspond to JTMSK.
|
||||
|
||||
use iso_c_binding, only: c_loc,c_size_t
|
||||
use hashing
|
||||
use packjt
|
||||
character msg*22,decoded*22
|
||||
integer*4 i4tone(234) !Channel symbols (values 0-1)
|
||||
integer*1 e1(201)
|
||||
integer*4 r1(201)
|
||||
real rd(201), tmp
|
||||
integer*1, target :: d8(13)
|
||||
integer mettab(0:255,0:1) !Metric table for BPSK modulation
|
||||
integer*1 i1hash(4)
|
||||
integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
|
||||
character*72 c72
|
||||
real xp(29)
|
||||
equivalence (ihash,i1hash)
|
||||
data xp/0.500000, 0.401241, 0.309897, 0.231832, 0.168095, &
|
||||
0.119704, 0.083523, 0.057387, 0.039215, 0.026890, &
|
||||
0.018084, 0.012184, 0.008196, 0.005475, 0.003808, &
|
||||
0.002481, 0.001710, 0.001052, 0.000789, 0.000469, &
|
||||
0.000329, 0.000225, 0.000187, 0.000086, 0.000063, &
|
||||
0.000017, 0.000091, 0.000032, 0.000045/
|
||||
|
||||
nmsg=1
|
||||
|
||||
! Get the metric table
|
||||
bias=0.0
|
||||
scale=20.0
|
||||
xln2=log(2.0)
|
||||
mettab=0
|
||||
do i=128,156
|
||||
x0=log(max(0.001,2.0*xp(i-127)))/xln2
|
||||
x1=log(max(0.001,2.0*(1-xp(i-127))))/xln2
|
||||
mettab(i,0)=nint(scale*(x0-bias))
|
||||
mettab(i,1)=nint(scale*(x1-bias))
|
||||
mettab(256-i,0)=mettab(i,1)
|
||||
mettab(256-i,1)=mettab(i,0)
|
||||
enddo
|
||||
do i=157,255
|
||||
mettab(i,0)=mettab(156,0)
|
||||
mettab(i,1)=mettab(156,1)
|
||||
mettab(256-i,0)=mettab(i,1)
|
||||
mettab(256-i,1)=mettab(i,0)
|
||||
enddo
|
||||
|
||||
rdscale=2.0
|
||||
ntrials=1000000
|
||||
rate=72.0/198.0
|
||||
msg="123"
|
||||
call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
|
||||
ichk=0
|
||||
call genmsk(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s
|
||||
|
||||
! Extract the data symbols, skipping over sync and parity bits
|
||||
n1=35
|
||||
n2=69
|
||||
n3=94
|
||||
|
||||
r1(1:n1)=i4tone(11+1:11+n1)
|
||||
r1(n1+1:n1+n2)=i4tone(23+n1+1:23+n1+n2)
|
||||
r1(n1+n2+1:n1+n2+n3)=i4tone(35+n1+n2+1:35+n1+n2+n3)
|
||||
|
||||
! call sgran()
|
||||
|
||||
do idb=6,11
|
||||
db=idb/2.0-0.5 ! Eb/N0=1/(2*R*sigma^2), so sigma= sqrt( 1/(2*R*Eb/N0) )
|
||||
sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
|
||||
|
||||
ngood=0 ! decoded = msg
|
||||
ngoodhash=0 ! will include undetected errors plus actual good ones
|
||||
|
||||
do itrial=1,ntrials
|
||||
do i=1,n1+n2+n3
|
||||
tmp=( 2.0 * ( r1(i)-0.5 ) + sigma*gran() )*rdscale
|
||||
if( tmp .lt. 0 ) then
|
||||
rd(i)=min(127.0,-tmp)
|
||||
elseif( tmp .gt.0 ) then
|
||||
rd(i)=max(-tmp,-127.0)
|
||||
endif
|
||||
enddo
|
||||
|
||||
j=0
|
||||
do i=1,99
|
||||
j=j+1
|
||||
e1(j)=rd(i)
|
||||
j=j+1
|
||||
e1(j)=rd(i+99)
|
||||
enddo
|
||||
|
||||
nb1=87
|
||||
call vit213(e1,nb1,mettab,d8,metric)
|
||||
|
||||
igoodhash=0
|
||||
ihash=nhash(c_loc(d8),int(9,c_size_t),146)
|
||||
ihash=2*iand(ihash,32767)
|
||||
decoded=" "
|
||||
if(d8(10).eq.i1hash(2) .and. d8(11).eq.i1hash(1)) then
|
||||
igoodhash=1
|
||||
write(c72,1012) d8(1:9)
|
||||
1012 format(9b8.8)
|
||||
read(c72,1014) i4Msg6BitWords
|
||||
1014 format(12b6.6)
|
||||
call unpackmsg(i4Msg6BitWords,decoded) !Unpack to get msgsent
|
||||
endif
|
||||
|
||||
if( igoodhash .eq. 1) ngoodhash=ngoodhash+1
|
||||
if( decoded .eq. msg ) ngood=ngood+1
|
||||
|
||||
enddo
|
||||
|
||||
write(*,1023) db,sigma,ntrials,ngood,ngoodhash-ngood
|
||||
1023 format("db:",f6.2," sigma:",f6.2," ntot:",i8," good:",i8," undet:",i8)
|
||||
enddo
|
||||
end program JTMSKfer
|
||||
@@ -1,93 +0,0 @@
|
||||
program JTMSKsim
|
||||
|
||||
use wavhdr
|
||||
parameter (NMAX=15*12000)
|
||||
real pings(0:NMAX-1)
|
||||
character arg*8,msg*22,msgsent*22,fname*40
|
||||
character*3 rpt(0:7)
|
||||
complex cmsg(0:1404-1) !Waveform of message (once)
|
||||
complex cwave(0:NMAX-1) !Simulated received waveform
|
||||
real*8 dt,twopi,freq,phi,dphi0,dphi1,dphi
|
||||
type(hdr) h !Header for .wav file
|
||||
integer*2 iwave(0:NMAX-1)
|
||||
integer itone(234) !Message bits
|
||||
integer b11(11) !Barker-11 code
|
||||
data b11/1,1,1,0,0,0,1,0,0,1,0/
|
||||
data rpt /'26 ','27 ','28 ','R26','R27','R28','RRR','73 '/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.5) then
|
||||
print*,'Usage: JTMSKsim message freq width snr nfiles'
|
||||
print*,' '
|
||||
print*,'Examples: JTMSKsim "K1ABC W9XYZ EN37" 1500 0.12 2 1'
|
||||
print*,' JTMSKsim "<K1ABC W9XYZ> R26" 1500 0.01 1 3'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,msg)
|
||||
call getarg(2,arg)
|
||||
read(arg,*) freq
|
||||
call getarg(3,arg)
|
||||
read(arg,*) width
|
||||
call getarg(4,arg)
|
||||
read(arg,*) snrdb
|
||||
call getarg(5,arg)
|
||||
read(arg,*) nfiles
|
||||
sig=10.0**(0.05*snrdb)
|
||||
twopi=8.d0*atan(1.d0)
|
||||
h=default_header(12000,NMAX)
|
||||
|
||||
ichk=0
|
||||
call genmsk(msg,ichk,msgsent,itone,itype) !Check message type
|
||||
if(itype.lt.1 .or. itype.gt.7) then
|
||||
print*,'Illegal message'
|
||||
go to 999
|
||||
endif
|
||||
dt=1.d0/12000.d0 !Sample interval
|
||||
dphi0=twopi*(freq-500.d0)*dt !Phase increment, lower tone
|
||||
dphi1=twopi*(freq+500.d0)*dt !Phase increment, upper tone
|
||||
|
||||
nsym=234
|
||||
if(itype.eq.7) nsym=35
|
||||
nspm=6*nsym !Samples per message
|
||||
k=-1
|
||||
phi=0.d0
|
||||
do j=1,nsym
|
||||
dphi=dphi0
|
||||
if(itone(j).eq.1) dphi=dphi1
|
||||
do i=1,6
|
||||
k=k+1
|
||||
phi=phi + dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
xphi=phi
|
||||
cmsg(k)=cmplx(cos(xphi),sin(xphi))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
call makepings(pings,NMAX,width,sig)
|
||||
|
||||
do ifile=1,nfiles !Loop over requested number of files
|
||||
write(fname,1002) ifile !Output filename
|
||||
1002 format('000000_',i4.4)
|
||||
open(10,file=fname(1:11)//'.wav',access='stream',status='unknown')
|
||||
|
||||
fac=sqrt(6000.0/2500.0)
|
||||
j=-1
|
||||
do i=0,NMAX-1
|
||||
j=j+1
|
||||
if(j.ge.6*nsym) j=j-6*nsym
|
||||
xx=0.707*gran()
|
||||
yy=0.707*gran()
|
||||
cwave(i)=pings(i)*cmsg(j) + fac*cmplx(xx,yy)
|
||||
iwave(i)=30.0*real(cwave(i))
|
||||
! write(88,3003) i,i/12000.d0,cwave(i)
|
||||
!3003 format(i8,f12.6,2f10.3)
|
||||
enddo
|
||||
|
||||
write(10) h,iwave !Save the .wav file
|
||||
close(10)
|
||||
|
||||
! call jtmsk_short(cwave,NMAX,msg)
|
||||
|
||||
enddo
|
||||
|
||||
999 end program JTMSKsim
|
||||
@@ -1,41 +0,0 @@
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RANLIB = ranlib
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -Wall -Wno-conversion -fbounds-check -fno-second-underscore -DUNIX
|
||||
CFLAGS = -I. -fPIE
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.mod: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
#all: jt4.mod testjt4 testfast9
|
||||
all: JTMSKsim
|
||||
|
||||
OBJS1 = JTMSKsim.o genmsk.o makepings.o genmsk_short.o jtmsk_short.o \
|
||||
hash.o nhash.o golay24_table.o vit213.o tab.o gran.o
|
||||
JTMSKsim: $(OBJS1)
|
||||
$(FC) -o JTMSKsim $(OBJS1) -L. libwsjt_fort.a -lfftw3f
|
||||
|
||||
nhash.o: wsprd/nhash.c
|
||||
$(CC) -c wsprd/nhash.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o JTMSKsim
|
||||
@@ -47,9 +47,6 @@ subroutine fast_decode(id2,narg,ntrperiod,bShMsgs,line, &
|
||||
if(nmode.eq.102) then
|
||||
call fast9(id2,narg,line)
|
||||
go to 900
|
||||
else if(nmode.eq.103) then
|
||||
call jtmsk_decode(id2,narg,line)
|
||||
go to 900
|
||||
else if(nmode.eq.104) then
|
||||
if(newdat.eq.1) then
|
||||
id2b=id2a
|
||||
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
subroutine genmsk(msg0,ichk,msgsent,i4tone,itype)
|
||||
|
||||
! Encode a JTMSK message
|
||||
! Input:
|
||||
! - msg0 requested message to be transmitted
|
||||
! - ichk if ichk=1, return only msgsent
|
||||
! if ichk.ge.10000, set imsg=ichk-10000 for short msg
|
||||
! - msgsent message as it will be decoded
|
||||
! - i4tone array of audio tone values, 0 or 1
|
||||
! - itype message type
|
||||
! 1 = standard message "Call_1 Call_2 Grid/Rpt"
|
||||
! 2 = type 1 prefix
|
||||
! 3 = type 1 suffix
|
||||
! 4 = type 2 prefix
|
||||
! 5 = type 2 suffix
|
||||
! 6 = free text (up to 13 characters)
|
||||
! 7 = short message "<Call_1 Call2> Rpt"
|
||||
|
||||
use iso_c_binding, only: c_loc,c_size_t
|
||||
use packjt
|
||||
use hashing
|
||||
character*22 msg0
|
||||
character*22 message !Message to be generated
|
||||
character*22 msgsent !Message as it will be received
|
||||
integer*4 i4Msg6BitWords(13) !72-bit message as 6-bit words
|
||||
integer*1, target:: i1Msg8BitBytes(13) !72 bits and zero tail as 8-bit bytes
|
||||
integer*1 e1(198) !Encoded bits before re-ordering
|
||||
integer*1 i1EncodedBits(198) !Encoded information-carrying bits
|
||||
integer i4tone(234) !Tone #s, data and sync (values 0-1)
|
||||
integer*1 i1hash(4)
|
||||
integer b11(11)
|
||||
data b11/1,1,1,0,0,0,1,0,0,1,0/ !Barker 11 code
|
||||
equivalence (ihash,i1hash)
|
||||
save
|
||||
|
||||
if(msg0(1:1).eq.'@') then !Generate a fixed tone
|
||||
read(msg0(2:5),*,end=1,err=1) nfreq !at specified frequency
|
||||
go to 2
|
||||
1 nfreq=1000
|
||||
2 i4tone(1)=nfreq
|
||||
else
|
||||
message=msg0
|
||||
do i=1,22
|
||||
if(ichar(message(i:i)).eq.0) then
|
||||
message(i:)=' '
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
|
||||
do i=1,22 !Strip leading blanks
|
||||
if(message(1:1).ne.' ') exit
|
||||
message=message(i+1:)
|
||||
enddo
|
||||
|
||||
if(message(1:1).eq.'<') then
|
||||
call genmsk_short(message,msgsent,ichk,i4tone,itype)
|
||||
if(itype.lt.0) go to 999
|
||||
i4tone(36)=-35
|
||||
go to 999
|
||||
endif
|
||||
|
||||
call packmsg(message,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
|
||||
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
|
||||
if(ichk.eq.1) go to 999
|
||||
call entail(i4Msg6BitWords,i1Msg8BitBytes) !Add tail, make 8-bit bytes
|
||||
ihash=nhash(c_loc(i1Msg8BitBytes),int(9,c_size_t),146)
|
||||
ihash=2*iand(ihash,32767) !Generate the CRC
|
||||
i1Msg8BitBytes(10)=i1hash(2) !CRC to bytes 10 and 11
|
||||
i1Msg8BitBytes(11)=i1hash(1)
|
||||
|
||||
nsym=198 !(72+12+15)*2 = 198
|
||||
kc=13
|
||||
nc=2
|
||||
nbits=87
|
||||
call enc213(i1Msg8BitBytes,nbits,e1,nsym,kc,nc) !Encode the message
|
||||
|
||||
j=0
|
||||
do i=1,nsym/2 !Reorder the encoded bits
|
||||
j=j+1
|
||||
i1EncodedBits(j)=e1(2*i-1)
|
||||
i1EncodedBits(j+99)=e1(2*i)
|
||||
enddo
|
||||
|
||||
! Insert three Barker 11 codes and three "even-f0-parity" bits
|
||||
i4tone=0 !Start with all 0's
|
||||
n1=35
|
||||
n2=69
|
||||
n3=94
|
||||
i4tone(1:11)=b11 !11 sync bits
|
||||
i4tone(11+1:11+n1)=i1EncodedBits(1:n1) !n1 data bits
|
||||
nn1=count(i4tone(11+1:11+n1).eq.0) !Count the 0's
|
||||
if(mod(nn1,2).eq.0) i4tone(12+n1)=1 !1 parity bit
|
||||
|
||||
i4tone(13+n1:23+n1)=b11 !11 sync bits
|
||||
i4tone(23+n1+1:23+n1+n2)=i1EncodedBits(n1+1:n1+n2) !n2 data bits
|
||||
nn2=count(i4tone(23+n1+1:23+n1+n2).eq.0) !Count the 0's
|
||||
if(mod(nn2,2).eq.0) i4tone(24+n1+n2)=1 !1 parity bit
|
||||
|
||||
i4tone(25+n1+n2:35+n1+n2)=b11 !11 sync bits
|
||||
i4tone(35+n1+n2+1:35+n1+n2+n3)=i1EncodedBits(n1+n2+1:n1+n2+n3)!n3 data bits
|
||||
nn3=count(i4tone(35+n1+n2+1:35+n1+n2+n3).eq.0) !Count the 0's
|
||||
if(mod(nn3,2).eq.0) i4tone(36+n1+n2+n3)=1 !1 parity bit
|
||||
endif
|
||||
|
||||
n=count(i4tone.eq.0)
|
||||
if(mod(n,2).ne.0) stop 'Parity error in genmsk.'
|
||||
|
||||
999 return
|
||||
end subroutine genmsk
|
||||
@@ -1,77 +0,0 @@
|
||||
program jtmsk
|
||||
|
||||
parameter (NMAX=359424)
|
||||
integer*2 id2(NMAX)
|
||||
integer narg(0:14)
|
||||
character*6 mycall,hiscall
|
||||
character*22 msg,arg*8
|
||||
character*80 line(100)
|
||||
character*60 line0
|
||||
character infile*80
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.lt.4) then
|
||||
print*,'Usage: jtmsk MyCall HisCall ntol infile1 [infile2 ...]'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,mycall)
|
||||
call getarg(2,hiscall)
|
||||
msg='<'//mycall//' '//hiscall//'> 26'
|
||||
call fmtmsg(msg,iz)
|
||||
call hash_calls(msg,narg(12))
|
||||
call getarg(3,arg)
|
||||
read(arg,*) ntol
|
||||
|
||||
nfiles=nargs-3
|
||||
tsync1=0.
|
||||
tsync2=0.
|
||||
tsoft=0.
|
||||
tvit=0.
|
||||
ttotal=0.
|
||||
ndecodes=0
|
||||
|
||||
call timer('jtmsk ',0)
|
||||
do ifile=1,nfiles
|
||||
call getarg(ifile+3,infile)
|
||||
open(10,file=infile,access='stream',status='old')
|
||||
read(10) id2(1:22) !Skip 44 header bytes
|
||||
npts=179712 !### T/R = 15 s
|
||||
read(10,end=1) id2(1:npts) !Read the raw data
|
||||
1 close(10)
|
||||
i1=index(infile,'.wav')
|
||||
read(infile(i1-6:i1-1),*) narg(0)
|
||||
|
||||
nrxfreq=1500
|
||||
narg(1)=npts !npts
|
||||
narg(2)=0 !nsubmode
|
||||
narg(3)=1 !newdat
|
||||
narg(4)=0 !minsync
|
||||
narg(5)=0 !npick
|
||||
narg(6)=0 !t0 (ms)
|
||||
narg(7)=npts/12 !t1 (ms) ???
|
||||
narg(8)=2 !maxlines
|
||||
narg(9)=103 !nmode
|
||||
narg(10)=nrxfreq
|
||||
narg(11)=ntol
|
||||
|
||||
call timer('jtmsk_de',0)
|
||||
call jtmsk_decode(id2,narg,line)
|
||||
call timer('jtmsk_de',1)
|
||||
do i=1,narg(8)
|
||||
if(line(i)(1:1).eq.char(0)) exit
|
||||
ndecodes=ndecodes+1
|
||||
line0=line(i)(1:60)
|
||||
i1=index(line(i)(1:60),'<...>')
|
||||
if(i1.gt.0 .and. narg(13)/8.eq.narg(12)) then
|
||||
i2=index(msg,'>')
|
||||
line0=line(i)(1:i1-1)//msg(1:i2)//line(i)(i1+5:i1+10)
|
||||
endif
|
||||
write(*,1002) line0,ndecodes
|
||||
1002 format(a60,i10)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
call timer('jtmsk ',1)
|
||||
call timer('jtmsk ',101)
|
||||
|
||||
999 end program jtmsk
|
||||
@@ -1,119 +0,0 @@
|
||||
subroutine jtmsk_decode(id2,narg,line)
|
||||
|
||||
! Decoder for JTMSK mode
|
||||
|
||||
parameter (NMAX=30*12000)
|
||||
parameter (NFFTMAX=512*1024)
|
||||
parameter (NSPM=1404) !Samples per JTMSK long message
|
||||
integer*2 id2(0:NMAX) !Raw i*2 data, up to T/R = 30 s
|
||||
integer hist(0:32868)
|
||||
real d(0:NMAX) !Raw r*4 data
|
||||
real ty(NMAX/512) !Ping times
|
||||
real yellow(NMAX/512)
|
||||
complex c(NFFTMAX) !Complex (analytic) data
|
||||
complex cdat(24000) !Short segments, up to 2 s
|
||||
complex cdat2(24000)
|
||||
integer narg(0:14) !Arguments passed from calling pgm
|
||||
character*22 msg,msg0 !Decoded message
|
||||
character*80 line(100) !Decodes passed back to caller
|
||||
equivalence (hist,d)
|
||||
|
||||
! Parameters from GUI are in narg():
|
||||
nutc=narg(0) !UTC
|
||||
npts=min(narg(1),NMAX) !Number of samples in id2 (12000 Hz)
|
||||
newdat=narg(3) !1==> new data, compute symbol spectra
|
||||
minsync=narg(4) !Lower sync limit
|
||||
npick=narg(5)
|
||||
t0=0.001*narg(6)
|
||||
t1=0.001*narg(7)
|
||||
maxlines=narg(8) !Max # of decodes to return to caller
|
||||
nmode=narg(9)
|
||||
nrxfreq=narg(10) !Target Rx audio frequency (Hz)
|
||||
ntol=narg(11) !Search range, +/- ntol (Hz)
|
||||
nhashcalls=narg(12)
|
||||
naggressive=narg(14)
|
||||
nsnr0=-99
|
||||
nline=0
|
||||
line(1:100)(1:1)=char(0)
|
||||
msg0=' '
|
||||
msg=msg0
|
||||
|
||||
hist=0
|
||||
do i=0,npts-1
|
||||
n=abs(id2(i))
|
||||
hist(n)=hist(n)+1
|
||||
enddo
|
||||
ns=0
|
||||
do n=0,32768
|
||||
ns=ns+hist(n)
|
||||
if(ns.gt.npts/2) exit
|
||||
enddo
|
||||
fac=1.0/(1.5*n)
|
||||
d(0:npts-1)=fac*id2(0:npts-1)
|
||||
! rms=sqrt(dot_product(d(0:npts-1),d(0:npts-1))/npts)
|
||||
!### Would it be better to set median rms to 1.0 ?
|
||||
! d(0:npts-1)=d(0:npts-1)/rms !Normalize so that rms=1.0
|
||||
call mskdt(d,npts,ty,yellow,nyel)
|
||||
nyel=min(nyel,5)
|
||||
|
||||
n=log(float(npts))/log(2.0) + 1.0
|
||||
nfft=min(2**n,1024*1024)
|
||||
call analytic(d,npts,nfft,c) !Convert to analytic signal and filter
|
||||
|
||||
nbefore=NSPM
|
||||
nafter=4*NSPM
|
||||
! Process ping list (sorted by S/N) from top down.
|
||||
do n=1,nyel
|
||||
ia=ty(n)*12000.0 - nbefore
|
||||
if(ia.lt.1) ia=1
|
||||
ib=ia + nafter
|
||||
if(ib.gt.NFFTMAX) ib=NFFTMAX
|
||||
iz=ib-ia+1
|
||||
cdat2(1:iz)=c(ia:ib) !Select nlen complex samples
|
||||
ja=ia/NSPM + 1
|
||||
jb=ib/NSPM
|
||||
t0=ia/12000.0
|
||||
|
||||
do itry=1,21
|
||||
idf1=(itry/2) * 50
|
||||
if(mod(itry,2).eq.1) idf1=-idf1
|
||||
if(abs(idf1).gt.ntol) exit
|
||||
fpk=idf1 + nrxfreq
|
||||
call tweak1(cdat2,iz,1500.0-fpk,cdat)
|
||||
call syncmsk(cdat,iz,jpk,ipk,idf,rmax,snr,metric,msg)
|
||||
if(metric.eq.-9999) cycle !No output if no significant sync
|
||||
if(msg(1:1).eq.' ') call jtmsk_short(cdat,iz,narg,tbest,idfpk,msg)
|
||||
if(msg(1:1).eq.'<' .and. naggressive.eq.0 .and. &
|
||||
narg(13)/8.ne.narg(12)) msg=' '
|
||||
if(msg(1:1).ne.' ') then
|
||||
if(msg.ne.msg0) then
|
||||
nline=nline+1
|
||||
nsnr0=-99
|
||||
endif
|
||||
freq=fpk+idf
|
||||
t0=(ia+jpk)/12000.0
|
||||
y=10.0**(0.1*(yellow(n)-1.5))
|
||||
nsnr=max(-5,nint(db(y)))
|
||||
if(nsnr.gt.nsnr0 .and. nline.gt.0) then
|
||||
call rectify_msk(cdat2(jpk:jpk+NSPM-1),msg,narg(13),freq2)
|
||||
freq=freq2
|
||||
if(msg(1:1).eq.'<') freq=freq2+idfpk
|
||||
!### Check freq values !!!
|
||||
write(line(nline),1020) nutc,nsnr,t0,nint(freq),msg
|
||||
1020 format(i6.6,i4,f5.1,i5,' & ',a22)
|
||||
nsnr0=nsnr
|
||||
go to 900
|
||||
endif
|
||||
msg0=msg
|
||||
if(nline.ge.maxlines) go to 900
|
||||
endif
|
||||
enddo
|
||||
! print*,'c',nutc,n,nint(yellow(n)-4.0),freq,freq2
|
||||
enddo
|
||||
|
||||
900 continue
|
||||
! print*,'d',nutc,n,nint(yellow(n)-4.0),freq,freq2
|
||||
if(line(1)(1:6).eq.' ') line(1)(1:1)=char(0)
|
||||
|
||||
return
|
||||
end subroutine jtmsk_decode
|
||||
@@ -1,161 +0,0 @@
|
||||
subroutine jtmsk_short(cdat,npts,narg,tbest,idfpk,decoded)
|
||||
|
||||
! Decode short-format messages in JTMSK mode.
|
||||
|
||||
parameter (NMAX=15*12000,NSAVE=100)
|
||||
character*22 msg,decoded,msgsent
|
||||
character*3 rpt(0:7)
|
||||
complex cdat(0:npts-1)
|
||||
complex cw(0:209,0:4095) !Waveforms of possible messages
|
||||
complex cb11(0:65) !Complex waveform of Barker 11
|
||||
complex cd(0:511)
|
||||
complex z1,z2a,z2b
|
||||
real*8 dt,twopi,freq,phi,dphi0,dphi1,dphi
|
||||
real r1(0:NMAX-1)
|
||||
real r2(0:4095)
|
||||
real r1save(NSAVE)
|
||||
integer itone(234) !Message bits
|
||||
integer jgood(NSAVE)
|
||||
integer indx(NSAVE)
|
||||
integer narg(0:14)
|
||||
logical first
|
||||
data rpt /'26 ','27 ','28 ','R26','R27','R28','RRR','73 '/
|
||||
data first/.true./,nrxfreq0/-1/,ttot/0.0/
|
||||
save first,cw,cb11,nrxfreq0,ttot
|
||||
|
||||
nrxfreq=narg(10) !Target Rx audio frequency (Hz)
|
||||
ntol=narg(11) !Search range, +/- ntol (Hz)
|
||||
nhashcalls=narg(12)
|
||||
|
||||
if(first .or. nrxfreq.ne.nrxfreq0) then
|
||||
dt=1.d0/12000.d0
|
||||
twopi=8.d0*atan(1.d0)
|
||||
freq=nrxfreq
|
||||
dphi0=twopi*(freq-500.d0)*dt !Phase increment, lower tone
|
||||
dphi1=twopi*(freq+500.d0)*dt !Phase increment, upper tone
|
||||
nsym=35 !Number of symbols
|
||||
nspm=6*nsym !Samples per message
|
||||
|
||||
msg="<C1ALL C2ALL> 73"
|
||||
do imsg=0,4095 !Generate all possible message waveforms
|
||||
ichk=10000+imsg
|
||||
call genmsk(msg,ichk,msgsent,itone,itype) !Encode the message
|
||||
k=-1
|
||||
phi=0.d0
|
||||
do j=1,nsym
|
||||
dphi=dphi0
|
||||
if(itone(j).eq.1) dphi=dphi1
|
||||
do i=1,6
|
||||
k=k+1
|
||||
phi=phi + dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
xphi=phi
|
||||
cw(k,imsg)=cmplx(cos(xphi),sin(xphi))
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
cb11=cw(0:65,0)
|
||||
first=.false.
|
||||
nrxfreq0=nrxfreq
|
||||
endif
|
||||
|
||||
r1thresh=0.80
|
||||
maxdecodes=999
|
||||
|
||||
r1max=0.
|
||||
do j=0,npts-210 !Find the B11 sync vectors
|
||||
z1=0.
|
||||
ss=0.
|
||||
do i=0,65
|
||||
ss=ss + real(cdat(j+i))**2 + aimag(cdat(j+i))**2
|
||||
z1=z1 + cdat(j+i)*conjg(cb11(i)) !Signal matching B11
|
||||
enddo
|
||||
ss=sqrt(ss/66.0)*66.0
|
||||
r1(j)=abs(z1)/(0.908*ss) !Goodness-of-fit to B11
|
||||
if(r1(j).gt.r1max) then
|
||||
r1max=r1(j)
|
||||
jpk=j
|
||||
endif
|
||||
enddo
|
||||
|
||||
k=0
|
||||
do j=1,npts-211
|
||||
if(r1(j).gt.r1thresh .and. r1(j).ge.r1(j-1) .and. r1(j).ge.r1(j+1) ) then
|
||||
k=k+1
|
||||
jgood(k)=j
|
||||
r1save(k)=r1(j)
|
||||
if(k.ge.NSAVE) exit
|
||||
endif
|
||||
enddo
|
||||
kmax=k
|
||||
call indexx(r1save,kmax,indx)
|
||||
|
||||
df=12000.0/512.0
|
||||
ibest2=-1
|
||||
idfbest=0
|
||||
u1best=0.
|
||||
do kk=1,min(kmax,10)
|
||||
k=indx(kmax+1-kk)
|
||||
j=jgood(k)
|
||||
if(j.lt.144 .or. j.gt.npts-210) cycle
|
||||
t=j/12000.0
|
||||
u1=0.
|
||||
u2=0.
|
||||
r2max=0.
|
||||
ibest=-1
|
||||
|
||||
do iidf=0,10
|
||||
idf=20*((iidf+1)/2)
|
||||
if(idf.gt.ntol) exit
|
||||
if(iand(iidf,1).eq.1) idf=-idf
|
||||
call tweak1(cdat(j-144:j+209),354,float(-idf),cd)
|
||||
cd(354:)=0.
|
||||
do imsg=0,4095
|
||||
ssa=0.
|
||||
ssb=0.
|
||||
do i=0,209
|
||||
ssa=ssa + real(cd(144+i))**2 + aimag(cd(144+i))**2
|
||||
ssb=ssb + real(cd(i))**2 + aimag(cdat(i))**2
|
||||
enddo
|
||||
|
||||
z2a=dot_product(cw(0:209,imsg),cd(144:353))
|
||||
z2b=dot_product(cw(0:65,imsg),cdat(144:209)) + &
|
||||
dot_product(cw(66:209,imsg),cdat(0:143))
|
||||
ssa=sqrt(ssa/210.0)*210.0
|
||||
ssb=sqrt(ssb/210.0)*210.0
|
||||
r2(imsg)=max(abs(z2a)/ssa,abs(z2b)/ssb)
|
||||
if(r2(imsg).gt.r2max) then
|
||||
r2max=r2(imsg)
|
||||
ibest=imsg
|
||||
u2=u1
|
||||
u1=r2max
|
||||
idfpk=idf
|
||||
t2=t
|
||||
n=0
|
||||
if(imsg.eq.2296 .or. imsg.eq.2302) n=1
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
|
||||
r1_r2=r1(j)/r2max
|
||||
if(u1.ge.0.71 .and. u2/u1.lt.0.91 .and. r1_r2.lt.1.3) then
|
||||
if(u1.gt.u1best) then
|
||||
irpt=iand(ibest,7)
|
||||
ihash=ibest/8
|
||||
narg(13)=ibest
|
||||
decoded="<...> "//rpt(irpt)
|
||||
tbest=t
|
||||
r1best=r1(j)
|
||||
u1best=u1
|
||||
u2best=u2
|
||||
ibest2=ibest
|
||||
idfbest=idfpk
|
||||
r1_r2best=r1_r2
|
||||
nn=0
|
||||
if(ihash.eq.narg(12) .and. iand(ibest2,7).eq.0) nn=1
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine jtmsk_short
|
||||
Reference in New Issue
Block a user