mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-26 22:28:41 -05:00
Functioning JTMSK decoder, within stand-alone program msk.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/jtms3@2519 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
40b0aaaf08
commit
3ba268cf14
@ -1,6 +1,6 @@
|
||||
[Setup]
|
||||
AppName=JTMS3
|
||||
AppVerName=JTMS3 Version 0.2 r2516
|
||||
AppVerName=JTMS3 Version 0.2 r2517
|
||||
AppCopyright=Copyright (C) 2001-2012 by Joe Taylor, K1JT
|
||||
DefaultDirName=c:\JTMS3
|
||||
DefaultGroupName=JTMS3
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
QT += core gui network
|
||||
CONFIG += qwt thread
|
||||
#CONFIG += console
|
||||
CONFIG += console
|
||||
|
||||
TARGET = jtms3
|
||||
VERSION = 0.1
|
||||
VERSION = 0.2
|
||||
TEMPLATE = app
|
||||
|
||||
win32 {
|
||||
|
@ -17,7 +17,7 @@ CFLAGS = -I. -fbounds-check
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libm65.a ms3.exe t1.exe
|
||||
all: libm65.a msk.exe
|
||||
|
||||
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
|
||||
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
|
||||
@ -32,15 +32,17 @@ OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
|
||||
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
|
||||
gen65.o chkmsg.o ptt.o astrosub.o astro0.o recvpkt.o symspec.o \
|
||||
iqcal.o iqfix.o timf2.o s3avg.o genjtms3.o analytic.o \
|
||||
db.o specjtms.o genmsk.o
|
||||
db.o specjtms.o genmsk.o mskdf.o tweak1.o syncmsk.o \
|
||||
lenmsk.o decodemsk.o ping.o makepings.o alignmsg.o match.o \
|
||||
rtping.o jtmsk.o hipass.o setupmsk.o foldmsk.o
|
||||
|
||||
libm65.a: $(OBJS1)
|
||||
ar cr libm65.a $(OBJS1)
|
||||
ranlib libm65.a
|
||||
|
||||
OBJS3 = ms3.o
|
||||
ms3.exe: $(OBJS3) libm65.a
|
||||
$(FC) -o ms3.exe $(OBJS3) libm65.a ../libfftw3f_win.a \
|
||||
OBJS3 = msk.o
|
||||
msk.exe: $(OBJS3) libm65.a
|
||||
$(FC) -o msk.exe $(OBJS3) libm65.a ../libfftw3f_win.a
|
||||
|
||||
OBJS2 = JT65code.o
|
||||
JT65code.exe: $(OBJS2) libm65.a
|
||||
|
@ -2,9 +2,10 @@ subroutine analytic(d,npts,nfft,s,c)
|
||||
|
||||
! Convert real data to analytic signal
|
||||
|
||||
parameter (NFFTMAX=128*1024)
|
||||
real d(npts)
|
||||
real s(npts)
|
||||
complex c(npts)
|
||||
complex c(NFFTMAX)
|
||||
|
||||
nh=nfft/2
|
||||
fac=2.0/nfft
|
||||
|
39
libm65/decodemsk.f90
Normal file
39
libm65/decodemsk.f90
Normal file
@ -0,0 +1,39 @@
|
||||
subroutine decodemsk(cdat,npts,cw,i1,nchar,s2,msg)
|
||||
|
||||
! DF snd sync have been established, now decode the message
|
||||
|
||||
complex cdat(npts)
|
||||
complex cw(168,0:63) !Complex waveforms for codewords
|
||||
real s2(0:63,400)
|
||||
character msg*400
|
||||
complex z,zmax
|
||||
character cc*64
|
||||
! 1 2 3 4 5 6
|
||||
! 0123456789012345678901234567890123456789012345678901234567890123
|
||||
data cc/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./?- _ @'/
|
||||
|
||||
msg=' '
|
||||
do j=1,nchar !Find best match for each character
|
||||
ia=i1 + (j-1)*168
|
||||
smax=0.
|
||||
do k=0,40
|
||||
kk=k
|
||||
if(k.eq.40) kk=57
|
||||
z=0.
|
||||
do i=1,168
|
||||
z=z + cdat(ia+i)*conjg(cw(i,kk))
|
||||
enddo
|
||||
ss=abs(z)
|
||||
s2(k,j)=ss
|
||||
if(ss.gt.smax) then
|
||||
smax=ss
|
||||
zmax=z
|
||||
kpk=kk
|
||||
endif
|
||||
enddo
|
||||
msg(j:j)=cc(kpk+1:kpk+1)
|
||||
if(kpk.eq.57) msg(j:j)=' '
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine decodemsk
|
50
libm65/foldmsk.f90
Normal file
50
libm65/foldmsk.f90
Normal file
@ -0,0 +1,50 @@
|
||||
subroutine foldmsk(s2,msglen,nchar,mycall,msg,msg29)
|
||||
|
||||
! Fold the 2-d "goodness of fit" array s2 modulo message length,
|
||||
! then decode the folded message.
|
||||
|
||||
real s2(0:63,400)
|
||||
real fs2(0:63,29)
|
||||
integer nfs2(29)
|
||||
character mycall*12
|
||||
character msg*400,msg29*29
|
||||
character cc*64
|
||||
! 1 2 3 4 5 6
|
||||
! 0123456789012345678901234567890123456789012345678901234567890123
|
||||
data cc/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./?- _ @'/
|
||||
|
||||
fs2=0.
|
||||
nfs2=0
|
||||
do j=1,nchar !Fold s2 into fs2, modulo msglen
|
||||
jj=mod(j-1,msglen)+1
|
||||
nfs2(jj)=nfs2(jj)+1
|
||||
do i=0,40
|
||||
fs2(i,jj)=fs2(i,jj) + s2(i,j)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
msg=' '
|
||||
do j=1,msglen
|
||||
smax=0.
|
||||
do k=0,40
|
||||
if(fs2(k,j).gt.smax) then
|
||||
smax=fs2(k,j)
|
||||
kpk=k
|
||||
endif
|
||||
enddo
|
||||
if(kpk.eq.40) kpk=57
|
||||
msg(j:j)=cc(kpk+1:kpk+1)
|
||||
if(kpk.eq.57) msg(j:j)=' '
|
||||
enddo
|
||||
|
||||
msg29=msg(1:msglen)
|
||||
|
||||
call alignmsg(' ',2,msg29,msglen,idone)
|
||||
if(idone.eq.0) call alignmsg('CQ', 3,msg29,msglen,idone)
|
||||
if(idone.eq.0) call alignmsg('QRZ', 3,msg29,msglen,idone)
|
||||
if(idone.eq.0) call alignmsg(mycall,4,msg29,msglen,idone)
|
||||
if(idone.eq.0) call alignmsg(' ', 1,msg29,msglen,idone)
|
||||
msg29=adjustl(msg29)
|
||||
|
||||
return
|
||||
end subroutine foldmsk
|
@ -65,7 +65,6 @@ subroutine genmsk(msg28,iwave,nwave)
|
||||
f0=48000.d0/nsps
|
||||
dfgen=0.5d0*f0
|
||||
foffset=1500.d0 - f0
|
||||
print*,f0,dfgen,foffset
|
||||
t=0.d0
|
||||
k=0
|
||||
phi=0.d0
|
||||
@ -95,5 +94,9 @@ subroutine genmsk(msg28,iwave,nwave)
|
||||
if(isrch.eq.0) iwave(k+1:)=0
|
||||
nwave=k
|
||||
|
||||
! call makepings(iwave,nwave)
|
||||
! write(71) iwave
|
||||
! call flush(71)
|
||||
|
||||
return
|
||||
end subroutine genmsk
|
||||
|
86
libm65/jtmsk.f90
Normal file
86
libm65/jtmsk.f90
Normal file
@ -0,0 +1,86 @@
|
||||
subroutine jtmsk(dat,npts,cfile6,t2,mswidth,ndb,nrpt,Nfreeze, &
|
||||
ntol,MouseDF,pick)
|
||||
|
||||
! Decode a JTMS ping
|
||||
|
||||
parameter (NZ=30*48000)
|
||||
real dat(npts) !Raw data
|
||||
complex cdat(NZ) !Analytic form of signal
|
||||
character*6 cfile6 !FileID
|
||||
logical pick
|
||||
character*12 mycall,hiscall
|
||||
real s(NZ) !Power spectrum
|
||||
real s2(0:63,400)
|
||||
real r(60000)
|
||||
complex cw(168,0:63) !Complex waveforms for all codewords
|
||||
complex cwb(168) !Complex waveform for <space>
|
||||
logical first
|
||||
character msg*400,msg29*29
|
||||
character*90 line
|
||||
common/ccom/nline,tping(100),line(100)
|
||||
data first/.true./
|
||||
save first,cw,cwb
|
||||
save cdat !Fix its address, for four2
|
||||
|
||||
if(first) call setupmsk(cw,cwb) !Calculate waveforms for codewords
|
||||
first=.false.
|
||||
|
||||
nsps=24 !Samples per symbol
|
||||
f0=1000.0 !Nominal frequency for bit=0
|
||||
n=log(float(npts))/log(2.0) + 1.0
|
||||
nfft1=2**n !FFT length
|
||||
call analytic(dat,npts,nfft1,s,cdat) !Convert to analytic signal
|
||||
|
||||
call mskdf(cdat,npts,t2,nfft1,f0,nfreeze,mousedf,ntol, &
|
||||
dfx,snrsq2) !Get DF
|
||||
print*,'b',dfx,snrsq2
|
||||
sq2lim=7.0
|
||||
if(pick) sq2lim=5.0
|
||||
if(snrsq2.lt.sq2lim) go to 900 !Reject non-JTMS signals
|
||||
|
||||
call tweak1(cdat,npts,-dfx,cdat) !Mix to standard frequency
|
||||
|
||||
! DF is known, now establish character sync.
|
||||
|
||||
call syncmsk(cdat,npts,cwb,r,i1) !Get character sync
|
||||
|
||||
call lenmsk(r,npts,msglen) !Find message length
|
||||
|
||||
s2=0.
|
||||
nchar=(npts-168+1-i1)/168
|
||||
if(nchar.gt.400) nchar=400
|
||||
|
||||
call decodemsk(cdat,npts,cw,i1,nchar,s2,msg) !Decode the message
|
||||
print*,'B',i1,msglen,nchar
|
||||
print*,msg(1:nchar)
|
||||
|
||||
! ia=1
|
||||
! if(nchar.ge.40) ia=min(nchar/3,nchar-28)
|
||||
! ib=min(ia+28,nchar) !Can better limits ia, ib be found?
|
||||
! print*,'A',ia,ib,nchar
|
||||
! print*,msg(1:nchar)
|
||||
! msg29=adjustl(msg(ia:ib))
|
||||
msg=adjustl(msg)
|
||||
ib=min(nchar,45)
|
||||
ndf=nint(dfx)
|
||||
nchk=max(20,nint(1.5*msglen))
|
||||
|
||||
if(msglen.eq.0 .or. nchar.lt.nchk .or. pick) then
|
||||
if(nline.le.99) nline=nline+1
|
||||
tping(nline)=t2
|
||||
write(line(nline),1110) cfile6,t2,mswidth,ndb,nrpt,ndf,msg(1:45)
|
||||
1110 format(a6,f5.1,i5,i3,1x,i2.2,i5,5x,a45)
|
||||
endif
|
||||
|
||||
if(msglen.gt.0 .and. nchar.ge.nchk) then
|
||||
call foldmsk(s2,msglen,nchar,mycall,msg,msg29) !Decode folded message
|
||||
if(nline.le.99) nline=nline+1
|
||||
tping(nline)=t2
|
||||
write(line(nline),1120) cfile6,t2,mswidth,ndb,nrpt,ndf,msg29
|
||||
1120 format(a6,f5.1,i5,i3,1x,i2.2,i5,5x,a29,11x,'*')
|
||||
endif
|
||||
|
||||
900 continue
|
||||
|
||||
return
|
||||
end subroutine jtmsk
|
56
libm65/lenmsk.f90
Normal file
56
libm65/lenmsk.f90
Normal file
@ -0,0 +1,56 @@
|
||||
subroutine lenmsk(r,npts,msglen)
|
||||
|
||||
! Determine length of the user message in a JTMS ping.
|
||||
|
||||
real r(60000)
|
||||
real acf(4872)
|
||||
integer np(9)
|
||||
data np/5,7,9,11,13,17,19,23,29/ !Permissible message lengths
|
||||
save acf !Why necessary? (But don't remove!)
|
||||
|
||||
msglen=0 !Use ACF to find msg length
|
||||
if(npts.ge.8*168) then
|
||||
r=r-sum(r(1:npts))/npts
|
||||
acfmax=0.
|
||||
acf0=dot_product(r(1:npts),r(1:npts))
|
||||
kz=min(nint(0.75*npts),29*168)
|
||||
do k=8,kz
|
||||
fac=float(npts)/(npts-k)
|
||||
acf(k)=fac*dot_product(r(1:npts),r(1+k:npts+k))/acf0
|
||||
enddo
|
||||
call hipass(acf(8),kz-7,50)
|
||||
|
||||
do k=8,kz !Find acfmax, kpk
|
||||
if(acf(k).gt.acfmax) then
|
||||
acfmax=acf(k)
|
||||
kpk=k
|
||||
endif
|
||||
enddo
|
||||
|
||||
sumsq=0.
|
||||
n=0
|
||||
do k=8,kz !Find rms, skipping around kpk
|
||||
if(abs(k-kpk).gt.10) then
|
||||
sumsq=sumsq+acf(k)**2
|
||||
n=n+1
|
||||
endif
|
||||
enddo
|
||||
rms=sqrt(sumsq/n)
|
||||
acf=acf/rms !Normalize the acf
|
||||
|
||||
amax2=0.
|
||||
acflim=3.5
|
||||
do i=1,9
|
||||
k=168*np(i) !Check only the permitted lengths
|
||||
if(k.gt.kz) go to 10
|
||||
if(acf(k).gt.acflim .and. acf(k).gt.amax2) then
|
||||
amax2=acf(k) !Save best value >3.5 sigma
|
||||
msglen=np(i) !Save message length
|
||||
kpk2=k
|
||||
endif
|
||||
enddo
|
||||
10 continue
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine lenmsk
|
59
libm65/msk.f90
Normal file
59
libm65/msk.f90
Normal file
@ -0,0 +1,59 @@
|
||||
program msk
|
||||
|
||||
! Starting code for a JTMSK decoder.
|
||||
|
||||
parameter (NSMAX=30*48000)
|
||||
character*80 infile
|
||||
character*6 cfile6
|
||||
character*12 arg
|
||||
real dat(NSMAX)
|
||||
real x(NSMAX)
|
||||
complex cx(0:NSMAX/2)
|
||||
integer hdr(11)
|
||||
integer*2 id
|
||||
common/mscom/id(NSMAX),s1(215,703),s2(215,703)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.lt.1) then
|
||||
print*,'Usage: msk <snr>'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) snr
|
||||
|
||||
open(71,file='dat.71',form='unformatted',status='old')
|
||||
read(71) id
|
||||
cfile6='123400'
|
||||
|
||||
npts=30*48000
|
||||
kstep=2048
|
||||
minsigdb=6
|
||||
mousedf=0
|
||||
ntol=200
|
||||
|
||||
call random_number(x)
|
||||
nfft=NSMAX
|
||||
call four2a(x,nfft,1,-1,0)
|
||||
df=48000.0/nfft
|
||||
ia=nint(300.0/df)
|
||||
ib=nint(2800.0/df)
|
||||
cx(:ia)=0.
|
||||
cx(ib:)=0.
|
||||
call four2a(cx,nfft,1,1,-1)
|
||||
x(1)=0.
|
||||
sq=0.
|
||||
do i=1,NSMAX
|
||||
sq=sq + x(i)**2
|
||||
enddo
|
||||
rms=sqrt(sq/NSMAX)
|
||||
x=x/rms
|
||||
sig=(10.0**(0.05*snr))/32768.0
|
||||
dat=sig*id + x
|
||||
|
||||
k=0
|
||||
do iblk=1,npts/kstep
|
||||
k=k+kstep
|
||||
call rtping(dat,k,cfile6,MinSigdB,MouseDF,ntol)
|
||||
enddo
|
||||
|
||||
999 end program msk
|
49
libm65/msk0.f90
Normal file
49
libm65/msk0.f90
Normal file
@ -0,0 +1,49 @@
|
||||
program msk
|
||||
|
||||
! Starting code for a JTMSK decoder.
|
||||
|
||||
parameter (NSMAX=30*48000)
|
||||
character*80 infile
|
||||
character*6 cfile6
|
||||
real dat(NSMAX)
|
||||
integer hdr(11)
|
||||
integer*2 id
|
||||
common/mscom/id(NSMAX),s1(215,703),s2(215,703)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.lt.1) then
|
||||
print*,'Usage: msk file1 [file2 ...]'
|
||||
print*,' Reads data from *.wav files.'
|
||||
go to 999
|
||||
endif
|
||||
|
||||
npts=30*48000
|
||||
kstep=2048
|
||||
minsigdb=6
|
||||
mousedf=0
|
||||
ntol=200
|
||||
|
||||
do ifile=1,nargs
|
||||
call getarg(ifile,infile)
|
||||
open(10,file=infile,access='stream',status='old',err=998)
|
||||
read(10) hdr
|
||||
read(10) id
|
||||
close(10)
|
||||
hdr(1)=hdr(2)
|
||||
i1=index(infile,'.wav')
|
||||
cfile6=infile(i1-6:i1-1)
|
||||
dat=id
|
||||
|
||||
k=0
|
||||
do iblk=1,npts/kstep
|
||||
k=k+kstep
|
||||
call rtping(dat,k,cfile6,MinSigdB,MouseDF,ntol)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
go to 999
|
||||
|
||||
998 print*,'Cannot open file:'
|
||||
print*,infile
|
||||
|
||||
999 end program msk
|
75
libm65/mskdf.f90
Normal file
75
libm65/mskdf.f90
Normal file
@ -0,0 +1,75 @@
|
||||
subroutine mskdf(cdat,npts,t2,nfft1,f0,nfreeze,mousedf,ntol,dfx,snrsq2)
|
||||
|
||||
! Determine DF for a JTMS signal. Also find ferr, a measure of
|
||||
! frequency differerence between 1st and 2nd harmonic.
|
||||
! (Should be 0.000)
|
||||
|
||||
parameter (NZ=128*1024)
|
||||
complex cdat(npts)
|
||||
integer ntol
|
||||
real sq(NZ)
|
||||
real ccf(-2600:2600) !Correct limits?
|
||||
real tmp(NZ)
|
||||
complex c(NZ)
|
||||
data nsps/8/
|
||||
save c
|
||||
|
||||
df1=48000.0/nfft1
|
||||
nh=nfft1/2
|
||||
fac=1.0/(nfft1**2)
|
||||
|
||||
do i=1,npts
|
||||
c(i)=fac*cdat(i)**2
|
||||
enddo
|
||||
c(npts+1:nfft1)=0.
|
||||
call four2a(c,nfft1,1,-1,1)
|
||||
|
||||
! In the "doubled-frequencies" spectrum of squared cdat:
|
||||
fa=2.0*(f0-400)
|
||||
fb=2.0*(f0+400)
|
||||
j0=nint(2.0*f0/df1)
|
||||
ja=nint(fa/df1)
|
||||
jb=nint(fb/df1)
|
||||
jd=nfft1/nsps
|
||||
|
||||
do j=1,nh+1
|
||||
sq(j)=real(c(j))**2 + aimag(c(j))**2
|
||||
! if(j*df1.lt.6000.0) write(54,3009) j*df1,sq(j),db(sq(j))
|
||||
!3009 format(3f12.3)
|
||||
enddo
|
||||
|
||||
ccf=0.
|
||||
do j=ja,jb
|
||||
ccf(j-j0-1)=sq(j)+sq(j+jd)
|
||||
enddo
|
||||
|
||||
call pctile(ccf(ja-j0-1),tmp,jb-ja+1,50,base)
|
||||
ccf=ccf/base
|
||||
|
||||
if(NFreeze.gt.0) then
|
||||
fa=2.0*(f0+MouseDF-ntol)
|
||||
fb=2.0*(f0+MouseDF+ntol)
|
||||
endif
|
||||
ja=nint(fa/df1)
|
||||
jb=nint(fb/df1)
|
||||
|
||||
! rewind 51
|
||||
smax=0.
|
||||
do j=ja,jb
|
||||
k=j-j0-1
|
||||
if(ccf(k).gt.smax) then
|
||||
smax=ccf(k)
|
||||
jpk=j
|
||||
endif
|
||||
f=0.5*k*df1
|
||||
! write(51,3002) f,ccf(k)
|
||||
!3002 format(2f12.3)
|
||||
enddo
|
||||
! call flush(51)
|
||||
|
||||
fpk=(jpk-1)*df1
|
||||
dfx=0.5*fpk-f0
|
||||
snrsq2=smax
|
||||
|
||||
return
|
||||
end subroutine mskdf
|
42
libm65/ping.f90
Normal file
42
libm65/ping.f90
Normal file
@ -0,0 +1,42 @@
|
||||
subroutine ping(s,nz,dtbuf,slim,wmin,pingdat,nping)
|
||||
|
||||
! Detect pings and make note of their start time, duration, and peak strength.
|
||||
|
||||
real*4 s(nz)
|
||||
real*4 pingdat(3,100)
|
||||
logical inside
|
||||
|
||||
nping=0
|
||||
peak=0.
|
||||
inside=.false.
|
||||
snrlim=10.0**(0.1*slim) - 1.0
|
||||
sdown=10.0*log10(0.25*snrlim+1.0)
|
||||
|
||||
i0=0 !Silence compiler warnings.
|
||||
tstart=0.0
|
||||
do i=2,nz
|
||||
if(s(i).ge.slim .and. .not.inside) then
|
||||
i0=i
|
||||
tstart=i0*dtbuf
|
||||
inside=.true.
|
||||
peak=0.
|
||||
endif
|
||||
if(inside .and. s(i).gt.peak) then
|
||||
peak=s(i)
|
||||
endif
|
||||
if(inside .and. (s(i).lt.sdown .or. i.eq.nz)) then
|
||||
if(i.gt.i0) then
|
||||
if(dtbuf*(i-i0).ge.wmin) then
|
||||
if(nping.le.99) nping=nping+1
|
||||
pingdat(1,nping)=tstart
|
||||
pingdat(2,nping)=dtbuf*(i-i0)
|
||||
pingdat(3,nping)=peak
|
||||
endif
|
||||
inside=.false.
|
||||
peak=0.
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine ping
|
103
libm65/rtping.f90
Normal file
103
libm65/rtping.f90
Normal file
@ -0,0 +1,103 @@
|
||||
subroutine rtping(dat,k,cfile6,MinSigdB,MouseDF,ntol)
|
||||
|
||||
!subroutine rtping(dat,jz,nz,MinSigdB,MinWidth,NFreeze,DFTolerance, &
|
||||
! MouseDF,istart,pick,cfile6,mycall,hiscall,mode,ps0)
|
||||
|
||||
! Decode Multi-Tone FSK441 mesages.
|
||||
|
||||
parameter (NSMAX=30*48000)
|
||||
parameter (NZMAX=NSMAX/2048)
|
||||
real dat(NSMAX) !Raw audio data
|
||||
logical pick
|
||||
character*6 cfile6
|
||||
real sig(NZMAX) !Sq-law detected signal, sampled at 43 ms
|
||||
real sigdb(NZMAX) !Signal in dB, sampled at 43 ms
|
||||
real work(NZMAX)
|
||||
real pingdat(3,100)
|
||||
! character msg*40,msg3*3
|
||||
character*90 line
|
||||
common/ccom/nline,tping(100),line(100)
|
||||
data nping0/0/
|
||||
save
|
||||
|
||||
slim=MinSigdB
|
||||
! nf1=-ntol
|
||||
! nf2=ntol
|
||||
dt=1.0/48000.0
|
||||
kstep=2048
|
||||
! pick=.false.
|
||||
istart=1
|
||||
jz=k
|
||||
|
||||
! Find signal power
|
||||
j=k/kstep
|
||||
sig(j)=dot_product(dat(k-kstep+1:k),dat(k-kstep+1:k))/kstep
|
||||
if(j.lt.10) return
|
||||
|
||||
! Remove baseline, compute signal level in dB
|
||||
call pctile (sig,work,j,50,base1)
|
||||
do i=1,j
|
||||
sigdb(i)=db(sig(i)/base1)
|
||||
if(j.eq.703) write(13,3001) i,sig(i),sigdb(i)
|
||||
3001 format(i5,2e12.3)
|
||||
enddo
|
||||
|
||||
dtbuf=kstep*dt
|
||||
wmin=0.040
|
||||
call ping(sigdb,j,dtbuf,slim,wmin,pingdat,nping)
|
||||
|
||||
! If this is a "mouse pick" and no ping was found, force a pseudo-ping
|
||||
! at center of data.
|
||||
! if(pick.and.nping.eq.0) then
|
||||
! if(nping.le.99) nping=nping+1
|
||||
! pingdat(1,nping)=0.5*jz*dt
|
||||
! pingdat(2,nping)=0.16
|
||||
! pingdat(3,nping)=1.0
|
||||
! endif
|
||||
|
||||
do iping=1,nping
|
||||
! Find starting place and length of data to be analyzed:
|
||||
tstart=pingdat(1,iping)
|
||||
width=pingdat(2,iping)
|
||||
peak=pingdat(3,iping)
|
||||
! mswidth=10*nint(100.0*width)
|
||||
jj=(tstart-0.02)/dt
|
||||
if(jj.lt.1) jj=1
|
||||
jjz=nint((width+0.02)/dt)+1
|
||||
jjz=min(jjz,jz+1-jj)
|
||||
|
||||
! Compute average spectrum of this ping.
|
||||
! call spec441(dat(jj),jjz,ps,f0)
|
||||
|
||||
! Decode the message.
|
||||
! msg=' '
|
||||
! call longx(dat(jj),jjz,ps,DFTolerance,noffset,msg,msglen,bauderr)
|
||||
|
||||
! Assemble a signal report:
|
||||
nwidth=0
|
||||
if(width.ge.0.04) nwidth=1 !These might depend on NSPD
|
||||
if(width.ge.0.12) nwidth=2
|
||||
if(width.gt.1.00) nwidth=3
|
||||
nstrength=6
|
||||
if(peak.ge.11.0) nstrength=7
|
||||
if(peak.ge.17.0) nstrength=8
|
||||
if(peak.ge.23.0) nstrength=9
|
||||
! nrpt=10*nwidth + nstrength
|
||||
t2=tstart + dt*(istart-1)
|
||||
|
||||
jjzz=min(jjz,2*48000) !Max data size 2 s
|
||||
!###
|
||||
jjzz=14400
|
||||
jj=jj-200
|
||||
!###
|
||||
|
||||
if(nping.gt.nping0) then
|
||||
print*,'a',jj,jjzz,jj*dt,jjzz*dt,t2,width
|
||||
call jtmsk(dat(jj),jjzz,cfile6,t2,mswidth,int(peak),nrpt, &
|
||||
nfreeze,DFTolerance,MouseDF,pick)
|
||||
nping0=nping
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine rtping
|
51
libm65/setupmsk.f90
Normal file
51
libm65/setupmsk.f90
Normal file
@ -0,0 +1,51 @@
|
||||
subroutine setupmsk(cw,cwb)
|
||||
|
||||
! Calculate the JTMS character waveforms.
|
||||
|
||||
complex cw(168,0:63)
|
||||
complex cwb(168)
|
||||
integer nb(7)
|
||||
! real*8 twopi,dt,f0,f1
|
||||
character cc*64
|
||||
! 1 2 3 4 5 6
|
||||
! 0123456789012345678901234567890123456789012345678901234567890123
|
||||
data cc/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./?- _ @'/
|
||||
|
||||
nsps=24
|
||||
twopi=8.d0*atan(1.d0)
|
||||
dt=1.d0/48000.d0 !Sample interval
|
||||
f0=1000.d0
|
||||
f1=2000.d0
|
||||
dphi0=twopi*dt*f0
|
||||
dphi1=twopi*dt*f1
|
||||
|
||||
do i=0,63
|
||||
k=0
|
||||
m=0
|
||||
do n=5,0,-1 !Each character gets 6+1 bits
|
||||
k=k+1
|
||||
nb(k)=iand(1,ishft(i,-n))
|
||||
m=m+nb(k)
|
||||
enddo
|
||||
k=k+1
|
||||
nb(k)=iand(m,1) !Insert parity bit
|
||||
|
||||
phi=0.
|
||||
j=0
|
||||
do k=1,7 !Generate the waveform
|
||||
if(nb(k).eq.0) then
|
||||
dphi=dphi0
|
||||
else
|
||||
dphi=dphi1
|
||||
endif
|
||||
do ii=1,nsps
|
||||
j=j+1
|
||||
phi=phi+dphi
|
||||
cw(j,i)=cmplx(cos(phi),sin(phi))
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
cwb=cw(1:168,57)
|
||||
|
||||
return
|
||||
end subroutine setupmsk
|
38
libm65/syncmsk.f90
Normal file
38
libm65/syncmsk.f90
Normal file
@ -0,0 +1,38 @@
|
||||
subroutine syncmsk(cdat,npts,cwb,r,i1)
|
||||
|
||||
! Establish character sync within a JTMS ping.
|
||||
|
||||
complex cdat(npts) !Analytic signal
|
||||
complex cwb(168) !Complex waveform for 'space'
|
||||
real r(60000)
|
||||
real tmp(60000)
|
||||
integer hist(168),hmax(1)
|
||||
complex z
|
||||
|
||||
r=0.
|
||||
jz=npts-168+1
|
||||
do j=1,jz
|
||||
z=0.
|
||||
ss=0.
|
||||
do i=1,168
|
||||
ss=ss + abs(cdat(i+j-1)) !Total power
|
||||
z=z + cdat(i+j-1)*conjg(cwb(i)) !Signal matching <space>
|
||||
enddo
|
||||
r(j)=abs(z)/ss !Goodness-of-fit to <space>
|
||||
! write(52,3001) j/168.0,r(j),cdat(j)
|
||||
!3001 format(4f12.3)
|
||||
enddo
|
||||
|
||||
ncut=99.0*float(jz-10)/float(jz)
|
||||
call pctile(r,tmp,jz,ncut,rlim)
|
||||
hist=0
|
||||
do j=1,jz
|
||||
k=mod(j-1,168)+1
|
||||
if(r(j).gt.rlim) hist(k)=hist(k)+1
|
||||
enddo
|
||||
|
||||
hmax=maxloc(hist)
|
||||
i1=hmax(1)
|
||||
|
||||
return
|
||||
end subroutine syncmsk
|
@ -1309,7 +1309,7 @@ void MainWindow::ba2msg(QByteArray ba, char message[]) //ba2msg()
|
||||
{
|
||||
bool eom;
|
||||
eom=false;
|
||||
for(int i=0;i<22; i++) {
|
||||
for(int i=0;i<28; i++) {
|
||||
if((int)ba[i] == 0) eom=true;
|
||||
if(eom) {
|
||||
message[i]=32;
|
||||
@ -1317,7 +1317,7 @@ void MainWindow::ba2msg(QByteArray ba, char message[]) //ba2msg()
|
||||
message[i]=ba[i];
|
||||
}
|
||||
}
|
||||
message[22]=0;
|
||||
message[28]=0;
|
||||
}
|
||||
|
||||
void MainWindow::on_txFirstCheckBox_stateChanged(int nstate) //TxFirst
|
||||
|
Loading…
Reference in New Issue
Block a user