Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1222 changed files with 70382 additions and 406763 deletions
@@ -1,361 +0,0 @@
subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
lsubtract,nagain,iaptype,mygrid6,bcontest,sync0,f1,xdt,apsym,nharderrors,&
dmin,nbadcrc,ipass,iera,message,xsnr)
use timer_module, only: timer
include 'ft8_params.f90'
parameter(NRECENT=10,NP2=2812)
character message*22,msgsent*22
character*12 recent_calls(NRECENT)
character*6 mygrid6
logical bcontest
real a(5)
real s1(0:7,ND),s2(0:7,NN)
real ps(0:7)
real bmeta(3*ND),bmetap(3*ND)
real llr(3*ND),llra(3*ND),llr0(3*ND),llrap(3*ND) !Soft symbols
real dd0(15*12000)
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
integer*1 msgbits(KK)
integer apsym(KK)
integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
integer itone(NN)
integer icos7(0:6),ip(1)
integer nappasses(0:5) ! the number of decoding passes to use for each QSO state
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
complex cd0(3200)
complex ctwk(32)
complex csymb(32)
logical first,newdat,lsubtract,lapon,nagain
data icos7/2,5,6,0,4,1,3/
data mcq/1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1/
data mrrr/0,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1/
data m73/0,1,1,1,1,1,1,0,1,1,0,1,0,0,0,0/
data mde/1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,0,1/
data mrr73/0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1/
data first/.true./
save nappasses,naptypes
if(first) then
mcq=2*mcq-1
mde=2*mde-1
mrrr=2*mrrr-1
m73=2*m73-1
mrr73=2*mrr73-1
nappasses(0)=2
nappasses(1)=2
nappasses(2)=2
nappasses(3)=4
nappasses(4)=4
nappasses(5)=3
! iaptype
!------------------------
! 1 CQ ??? ???
! 2 MyCall ??? ???
! 3 MyCall DxCall ???
! 4 MyCall DxCall RRR
! 5 MyCall DxCall 73
! 6 MyCall DxCall RR73
! 7 ??? DxCall ???
naptypes(0,1:4)=(/1,2,0,0/)
naptypes(1,1:4)=(/2,3,0,0/)
naptypes(2,1:4)=(/2,3,0,0/)
naptypes(3,1:4)=(/3,4,5,6/)
naptypes(4,1:4)=(/3,4,5,6/)
naptypes(5,1:4)=(/3,1,2,0/) !?
first=.false.
endif
max_iterations=30
nharderrors=-1
fs2=12000.0/NDOWN
dt2=1.0/fs2
twopi=8.0*atan(1.0)
delfbest=0.
ibest=0
call timer('ft8_down',0)
call ft8_downsample(dd0,newdat,f1,cd0) !Mix f1 to baseband and downsample
call timer('ft8_down',1)
i0=nint((xdt+0.5)*fs2) !Initial guess for start of signal
smax=0.0
do idt=i0-8,i0+8 !Search over +/- one quarter symbol
call sync8d(cd0,idt,ctwk,0,sync)
if(sync.gt.smax) then
smax=sync
ibest=idt
endif
enddo
xdt2=ibest*dt2 !Improved estimate for DT
! Now peak up in frequency
i0=nint(xdt2*fs2)
smax=0.0
do ifr=-5,5 !Search over +/- 2.5 Hz
delf=ifr*0.5
dphi=twopi*delf*dt2
phi=0.0
do i=1,32
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call sync8d(cd0,i0,ctwk,1,sync)
if( sync .gt. smax ) then
smax=sync
delfbest=delf
endif
enddo
a=0.0
a(1)=-delfbest
call twkfreq1(cd0,NP2,fs2,a,cd0)
xdt=xdt2
f1=f1+delfbest !Improved estimate of DF
call sync8d(cd0,i0,ctwk,2,sync)
j=0
do k=1,NN
i1=ibest+(k-1)*32
csymb=cmplx(0.0,0.0)
if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
s2(0:7,k)=abs(csymb(1:8))/1e3
enddo
! sync quality check
is1=0
is2=0
is3=0
do k=1,7
ip=maxloc(s2(:,k))
if(icos7(k-1).eq.(ip(1)-1)) is1=is1+1
ip=maxloc(s2(:,k+36))
if(icos7(k-1).eq.(ip(1)-1)) is2=is2+1
ip=maxloc(s2(:,k+72))
if(icos7(k-1).eq.(ip(1)-1)) is3=is3+1
enddo
! hard sync sum - max is 21
nsync=is1+is2+is3
if(nsync .le. 6) then ! bail out
nbadcrc=1
return
endif
j=0
do k=1,NN
if(k.le.7) cycle
if(k.ge.37 .and. k.le.43) cycle
if(k.gt.72) cycle
j=j+1
s1(0:7,j)=s2(0:7,k)
enddo
do j=1,ND
i4=3*j-2
i2=3*j-1
i1=3*j
ps=s1(0:7,j)
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
bmeta(i4)=r4
bmeta(i2)=r2
bmeta(i1)=r1
bmetap(i4)=r4
bmetap(i2)=r2
bmetap(i1)=r1
if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
if(j.eq.39) then ! take care of bits that live in symbol 39
if(apsym(28).lt.0) then
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
else
bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
endif
endif
endif
! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
! with ap bits 116 and 117. Take care of metric for bit 115.
! if(j.eq.39) then ! take care of bit 115
! iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
! if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
! if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
! if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
! if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
! endif
! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
! take care of metrics for bits 142 and 143
if(j.eq.48) then ! bit 144 is always 1
bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
endif
! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
! take care of metrics for bits 155 and 156
if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
endif
enddo
call normalizebmet(bmeta,3*ND)
call normalizebmet(bmetap,3*ND)
ss=0.84
llr0=2.0*bmeta/(ss*ss)
llra=2.0*bmetap/(ss*ss) ! llr's for use with ap
apmag=4.0
! pass #
!------------------------------
! 1 regular decoding
! 2 erase 24
! 3 erase 48
! 4 ap pass 1
! 5 ap pass 2
! 6 ap pass 3
! 7 ap pass 4, etc.
if(lapon) then
npasses=3+nappasses(nQSOProgress)
else
npasses=3
endif
do ipass=1,npasses
llr=llr0
if(ipass.eq.2) llr(1:24)=0.
if(ipass.eq.3) llr(1:48)=0.
if(ipass.le.3) then
apmask=0
llrap=llr
iaptype=0
endif
if(ipass .gt. 3) then
iaptype=naptypes(nQSOProgress,ipass-3)
if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
apmask=0
apmask(88:115)=1 ! first 28 bits are AP
apmask(144)=1 ! not free text
llrap=llr
if(iaptype.eq.1) llrap(88:115)=apmag*mcq/ss
if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)/ss
llrap(116:117)=llra(116:117)
llrap(142:143)=llra(142:143)
llrap(144)=-apmag/ss
endif
if(iaptype.eq.3) then ! mycall, dxcall, ???
apmask=0
apmask(88:115)=1 ! mycall
apmask(116:143)=1 ! hiscall
apmask(144)=1 ! not free text
llrap=llr
llrap(88:143)=apmag*apsym(1:56)/ss
llrap(144)=-apmag/ss
endif
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
apmask=0
apmask(88:115)=1 ! mycall
apmask(116:143)=1 ! hiscall
apmask(144:159)=1 ! RRR or 73 or RR73
llrap=llr
llrap(88:143)=apmag*apsym(1:56)/ss
if(iaptype.eq.4) llrap(144:159)=apmag*mrrr/ss
if(iaptype.eq.5) llrap(144:159)=apmag*m73/ss
if(iaptype.eq.6) llrap(144:159)=apmag*mrr73/ss
endif
if(iaptype.eq.7) then ! ???, dxcall, ???
apmask=0
apmask(116:143)=1 ! hiscall
apmask(144)=1 ! not free text
llrap=llr
llrap(115)=llra(115)
llrap(116:143)=apmag*apsym(29:56)/ss
llrap(144)=-apmag/ss
endif
endif
cw=0
call timer('bpd174 ',0)
call bpdecode174(llrap,apmask,max_iterations,decoded,cw,nharderrors, &
niterations)
call timer('bpd174 ',1)
dmin=0.0
if(ndepth.eq.3 .and. nharderrors.lt.0) then
ndeep=3
if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
if((ipass.eq.2 .or. ipass.eq.3) .and. .not.nagain) then
ndeep=3
else
ndeep=4
endif
endif
if(nagain) ndeep=5
call timer('osd174 ',0)
call osd174(llrap,apmask,ndeep,decoded,cw,nharderrors,dmin)
call timer('osd174 ',1)
endif
nbadcrc=1
message=' '
xsnr=-99.0
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
if(any(decoded(73:75).ne.0)) cycle !Reject if any of the 3 extra bits are nonzero
if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
.not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
.not.(ipass.gt.1 .and. nharderrors.gt.39) .and. &
.not.(ipass.eq.3 .and. nharderrors.gt.30) &
) then
call chkcrc12a(decoded,nbadcrc)
else
nharderrors=-1
cycle
endif
if(nbadcrc.eq.0) then
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
call genft8(message,mygrid6,bcontest,msgsent,msgbits,itone)
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
xsig=0.0
xnoi=0.0
do i=1,79
xsig=xsig+s2(itone(i),i)**2
ios=mod(itone(i)+4,7)
xnoi=xnoi+s2(ios,i)**2
enddo
xsnr=0.001
if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0
xsnr=10.0*log10(xsnr)-27.0
if(xsnr .lt. -24.0) xsnr=-24.0
return
endif
enddo
return
end subroutine ft8b
subroutine normalizebmet(bmet,n)
real bmet(n)
bmetav=sum(bmet)/real(n)
bmet2av=sum(bmet*bmet)/real(n)
var=bmet2av-bmetav*bmetav
if( var .gt. 0.0 ) then
bmetsig=sqrt(var)
else
bmetsig=sqrt(bmet2av)
endif
bmet=bmet/bmetsig
return
end subroutine normalizebmet
Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

@@ -1,236 +0,0 @@
set (LANGUAGES
en
)
set (common_SRCS
common/communication.adoc
common/license.adoc
common/links.adoc
)
set (UG_SRCS
docinfo.html
docinfo.xml
acknowledgements.adoc
astro_data.adoc
config-details.adoc
controls-functions-center.adoc
controls-functions-left.adoc
controls-functions-main-window.adoc
controls-functions-menus.adoc
controls-functions-messages.adoc
controls-functions-status-bar.adoc
controls-functions-wide-graph.adoc
cooperating-programs.adoc
decoder_notes.adoc
faq.adoc
font-sizes.adoc
install-from-source.adoc
install-linux.adoc
install-mac.adoc
install-windows.adoc
introduction.adoc
measurement_tools.adoc
protocols.adoc
logging.adoc
make-qso.adoc
new_features.adoc
platform-dependencies.adoc
protocols.adoc
settings-advanced.adoc
settings-audio.adoc
settings-colors.adoc
settings-frequencies.adoc
settings-general.adoc
settings-radio.adoc
settings-reporting.adoc
settings-txmacros.adoc
support.adoc
system-requirements.adoc
transceiver-setup.adoc
tutorial-example1.adoc
tutorial-example2.adoc
tutorial-example3.adoc
tutorial-main-window.adoc
tutorial-wide-graph-settings.adoc
utilities.adoc
vhf-features.adoc
wsjtx-main.adoc
wspr.adoc
)
set (UG_IMGS
images/130610_2343-wav-80.png
images/170709_135615.wav.png
images/AstroData_2.png
images/Astronomical_data.png
images/auto-seq.png
images/band-settings.png
images/colors.png
images/config-menu.png
images/decode-menu.png
images/decodes.png
images/download_samples.png
images/file-menu.png
images/freemsg.png
images/ft8_decodes.png
images/help-menu.png
images/JT4F.png
images/JT65B.png
images/MSK144.png
images/QRA64.png
images/WSPR_WideGraphControls.png
images/WSPR_1a.png
images/WSPR_2.png
images/jtalert.png
images/keyboard-shortcuts.png
images/log-qso.png
images/MacAppMenu.png
images/main-ui.png
images/main-ui-controls.png
images/misc-controls-center.png
images/misc-main-ui.png
images/mode-menu.png
images/new-msg-box.png
images/psk-reporter.png
images/r3666-config-screen-80.png
images/r3666-main-ui-80.png
images/r4148-txmac-ui.png
images/RadioTab.png
images/reporting.png
images/save-menu.png
images/settings-advanced.png
images/settings-audio.png
images/settings-frequencies.png
images/settings-general.png
images/setup-menu.png
images/special-mouse-commands.png
images/status-bar-a.png
images/tools-menu.png
images/traditional-msg-box.png
images/tx-macros.png
images/view-menu.png
images/wide-graph-controls.png
)
find_program (ASCIIDOCTOR_EXECUTABLE NAMES asciidoctor)
if (NOT ASCIIDOCTOR_EXECUTABLE)
message (FATAL_ERROR "asciidoctor is required to build the documentation
Building the documenation may optionally be turned off by setting the CMake
option WSJT_GENERATE_DOCS to OFF.")
endif (NOT ASCIIDOCTOR_EXECUTABLE)
find_program (FOPUB_EXECUTABLE NAMES fopub)
include (CMakeParseArguments)
# generate a document from asciidoc text files(s)
#
# HTML - generate an HTML document
# PDF - generate a PDF document
# SOURCE - top level asciidoc file
# ASCIIDOCTOR_OPTIONS - asciidoctor command options
# DEPENDS - dependent files
function (document)
cmake_parse_arguments (_args "HTML" "SOURCE;LANG;OUTPUT" "ASCIIDOCTOR_OPTIONS;PDF;DEPENDS" ${ARGN})
get_filename_component (_source_path ${_args_SOURCE} PATH)
get_filename_component (_source_name ${_args_SOURCE} NAME)
get_filename_component (_output_name_we ${_args_SOURCE} NAME_WE)
# HTML
if (${_args_HTML})
set (_html_file ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang}.html)
add_custom_command (
OUTPUT ${_html_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_source_path}/${lang}
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ${_args_ASCIIDOCTOR_OPTIONS}
-b html5
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
-a VERSION=${wsjtx_VERSION}
--out-file=${_html_file} ${_source_name}
DEPENDS ${_args_DEPENDS}
COMMENT "Generating ${_html_file}"
)
list (APPEND _output_files ${_html_file})
endif (${_args_HTML})
# PDF
if (_args_PDF AND EXISTS ${FOPUB_EXECUTABLE})
set (_docbook_file ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang}.xml)
set (_pdf_file_we ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang})
if (${lang} MATCHES "^(en|es|fr)$") # en-us, fr-ca and es-{mx,co} use US-Letter or equivalent
set (_usl_commands
COMMAND ${FOPUB_EXECUTABLE} ARGS ${_docbook_file} ${_args_PDF} -param paper.type USLetter
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_pdf_file_we}.pdf '${_pdf_file_we} \(USLetter\).pdf'
)
list (APPEND _output_files "${_pdf_file_we} (USLetter).pdf")
endif ()
list (APPEND _output_files "${_pdf_file_we}.pdf")
add_custom_command (
OUTPUT ${_docbook_file} ${_output_files}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_source_path}/${lang}
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ARGS ${_args_ASCIIDOCTOR_OPTIONS}
-b docbook
-a data-uri!
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
-a VERSION=${wsjtx_VERSION}
-D ${CMAKE_CURRENT_BINARY_DIR}
-o ${_docbook_file} ${_source_name}
${_usl_commands}
COMMAND ${FOPUB_EXECUTABLE} ARGS ${_docbook_file} ${_args_PDF} -param paper.type A4
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_pdf_file_we}.pdf '${_pdf_file_we}.pdf'
DEPENDS ${_args_DEPENDS}
COMMENT "Generating ${_output_files}"
)
endif (_args_PDF AND EXISTS ${FOPUB_EXECUTABLE})
set (${_args_OUTPUT} ${_output_files} PARENT_SCOPE)
endfunction (document)
set (htmls)
set (pdfs)
foreach (lang ${LANGUAGES})
set (_sources)
foreach (_src ${UG_SRCS} ${UG_IMGS})
list (APPEND _sources "user_guide/${lang}/${_src}")
endforeach ()
document(
HTML
SOURCE user_guide/wsjtx-main.adoc
LANG "${lang}"
OUTPUT html
ASCIIDOCTOR_OPTIONS -d book -a data-uri -a toc=left -a max-width=1024px
DEPENDS ${common_SRCS} ${_sources}
)
document(
PDF -param body.font.master 11 -param body.font.family "'Noto Sans, Helvetica, sans-serif'" -param title.font.family "'Noto Serif, Times New Roman, serif'" -param page.margin.inner 1cm -param page.margin.outer 1cm -param page.margin.top 0.75cm -param page.margin.bottom 0.5cm -param generate.toc 0
SOURCE user_guide/wsjtx-main.adoc
LANG "${lang}"
OUTPUT pdf
ASCIIDOCTOR_OPTIONS -d book
DEPENDS ${common_SRCS} ${_sources}
)
list (APPEND htmls "${html}")
list (APPEND pdfs "${pdf}")
endforeach ()
add_custom_target (docs ALL DEPENDS ${htmls} ${pdfs})
foreach (_html ${htmls})
get_filename_component (_path ${_html} PATH)
get_filename_component (_nwe ${_html} NAME_WE)
get_filename_component (_ext ${_html} EXT)
string (REGEX REPLACE "_en$" "" _nwe ${_nwe})
install (FILES
${_html}
DESTINATION ${CMAKE_INSTALL_DOCDIR}
RENAME ${_nwe}-${wsjtx_VERSION}${_ext}
#COMPONENT runtime
)
endforeach ()
@@ -1,258 +0,0 @@
subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
bshmsg,bcontest,btrain,pcoeffs,bswl,datadir,line)
! Real-time decoder for MSK144.
! Analysis block size = NZ = 7168 samples, t_block = 0.597333 s
! Called from hspec() at half-block increments, about 0.3 s
parameter (NZ=7168) !Block size
parameter (NSPM=864) !Number of samples per message frame
parameter (NFFT1=8192) !FFT size for making analytic signal
parameter (NPATTERNS=4) !Number of frame averaging patterns to try
parameter (NRECENT=10) !Number of recent calls to remember
parameter (NSHMEM=50) !Number of recent SWL messages to remember
character*3 decsym !"&" for mskspd or "^" for long averages
character*22 msgreceived !Decoded message
character*22 msglast,msglastswl !Used for dupechecking
character*80 line !Formatted line with UTC dB T Freq Msg
character*12 mycall,hiscall
character*6 mygrid
character*12 recent_calls(NRECENT)
character*22 recent_shmsgs(NSHMEM)
character*512 datadir
complex cdat(NFFT1) !Analytic signal
complex c(NSPM) !Coherently averaged complex data
complex ct(NSPM)
integer*2 id2(NZ) !Raw 16-bit data
integer iavmask(8)
integer iavpatterns(8,NPATTERNS)
integer npkloc(10)
integer nhasharray(NRECENT,NRECENT)
integer nsnrlast,nsnrlastswl
real d(NFFT1)
real pow(8)
real softbits(144)
real xmc(NPATTERNS)
real*8 pcoeffs(5)
logical*1 bshmsg,bcontest,btrain,bswl
logical*1 first
logical*1 bshdecode
logical*1 seenb4
logical*1 bflag
logical*1 bvar
data first/.true./
data iavpatterns/ &
1,1,1,1,0,0,0,0, &
0,0,1,1,1,1,0,0, &
1,1,1,1,1,0,0,0, &
1,1,1,1,1,1,1,0/
data xmc/2.0,4.5,2.5,3.5/ !Used to set time at center of averaging mask
save first,tsec0,nutc00,pnoise,cdat,msglast,msglastswl, &
nsnrlast,nsnrlastswl,recent_calls,nhasharray,recent_shmsgs
if(first) then
tsec0=tsec
nutc00=nutc0
pnoise=-1.0
do i=1,nrecent
recent_calls(i)(1:12)=' '
enddo
do i=1,nshmem
recent_shmsgs(i)(1:22)=' '
enddo
msglast=' '
msglastswl=' '
nsnrlast=-99
nsnrlastswl=-99
first=.false.
endif
fc=nrxfreq
! Dupe checking setup
if(nutc00.ne.nutc0 .or. tsec.lt.tsec0) then ! reset dupe checker
msglast=' '
msglastswl=' '
nsnrlast=-99
nsnrlastswl=-99
nutc00=nutc0
endif
tframe=float(NSPM)/12000.0
line=char(0)
msgreceived=' '
max_iterations=10
niterations=0
d(1:NZ)=id2
rms=sqrt(sum(d(1:NZ)*d(1:NZ))/NZ)
if(rms.lt.1.0) go to 999
fac=1.0/rms
d(1:NZ)=fac*d(1:NZ)
d(NZ+1:NFFT1)=0.
bvar=.true.
if( btrain ) bvar=.false. ! if training, turn off rx eq
call analytic(d,NZ,NFFT1,cdat,pcoeffs,bvar)
! Calculate average power for each frame and for the entire block.
! If decode is successful, largest power will be taken as signal+noise.
! If no decode, entire-block average will be used to update noise estimate.
pmax=-99
do i=1,8
ib=(i-1)*NSPM+1
ie=ib+NSPM-1
pow(i)=real(dot_product(cdat(ib:ie),cdat(ib:ie)))*rms**2
pmax=max(pmax,pow(i))
enddo
pavg=sum(pow)/8.0
! Short ping decoder uses squared-signal spectrum to determine where to
! center a 3-frame analysis window and attempts to decode each of the
! 3 frames along with 2- and 3-frame averages.
np=8*NSPM
call msk144spd(cdat,np,ntol,ndecodesuccess,msgreceived,fc,fest,tdec,navg,ct, &
softbits,recent_calls,nrecent)
if(ndecodesuccess.eq.0 .and. (bshmsg.or.bswl)) then
call msk40spd(cdat,np,ntol,mycall(1:6),hiscall(1:6),bswl,nhasharray, &
recent_calls,nrecent,ndecodesuccess,msgreceived,fc,fest,tdec,navg)
endif
if( ndecodesuccess .ge. 1 ) then
tdec=tsec+tdec
ipk=0
is=0
goto 900
endif
! If short ping decoder doesn't find a decode,
! Fast - short ping decoder only.
! Normal - try 4-frame averages
! Deep - try 4-, 5- and 7-frame averages.
npat=NPATTERNS
if( ndepth .eq. 1 ) npat=0
if( ndepth .eq. 2 ) npat=2
do iavg=1,npat
iavmask=iavpatterns(1:8,iavg)
navg=sum(iavmask)
deltaf=10.0/real(navg) ! search increment for frequency sync
npeaks=2
call msk144sync(cdat(1:8*NSPM),8,ntol,deltaf,iavmask,npeaks,fc, &
fest,npkloc,nsyncsuccess,xmax,c)
if( nsyncsuccess .eq. 0 ) cycle
do ipk=1,npeaks
do is=1,3
ic0=npkloc(ipk)
if(is.eq.2) ic0=max(1,ic0-1)
if(is.eq.3) ic0=min(NSPM,ic0+1)
ct=cshift(c,ic0-1)
call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, &
recent_calls,nrecent)
if(ndecodesuccess .gt. 0) then
tdec=tsec+xmc(iavg)*tframe
goto 900
endif
enddo !Slicer dither
enddo !Peak loop
enddo
msgreceived=' '
! no decode - update noise level used for calculating displayed snr.
if( pnoise .lt. 0 ) then ! initialize noise level
pnoise=pavg
elseif( pavg .gt. pnoise ) then ! noise level is slow to rise
pnoise=0.9*pnoise+0.1*pavg
elseif( pavg .lt. pnoise ) then ! and quick to fall
pnoise=pavg
endif
go to 999
900 continue
! Successful decode - estimate snr
if( pnoise .gt. 0.0 ) then
snr0=10.0*log10(pmax/pnoise-1.0)
else
snr0=0.0
endif
nsnr=nint(snr0)
bshdecode=.false.
if( msgreceived(1:1) .eq. '<' ) bshdecode=.true.
if(.not. bshdecode) then
call msk144signalquality(ct,snr0,fest,tdec,softbits,msgreceived,hiscall, &
btrain,datadir,ncorrected,eyeopening,pcoeffs)
endif
decsym=' & '
if( btrain ) decsym=' ^ '
if( msgreceived(1:1).eq.'<') then
ncorrected=0
eyeopening=0.0
endif
if( nsnr .lt. -8 ) nsnr=-8
if( nsnr .gt. 24 ) nsnr=24
! Dupe check.
bflag=ndecodesuccess.eq.1 .and. &
(msgreceived.ne.msglast .or. nsnr.gt.nsnrlast .or. tsec.lt.tsec0)
if(bflag) then
msglast=msgreceived
nsnrlast=nsnr
if(.not. bshdecode) then
call update_hasharray(recent_calls,nrecent,nhasharray)
! Should we call fix_contest_msg() only if bcontest is true?
call fix_contest_msg(mycall(1:6),mygrid,hiscall(1:6),msgreceived)
endif
write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
navg,ncorrected,eyeopening,char(0)
1020 format(i6.6,i4,f5.1,i5,a3,a22,i2,i3,f5.1,a1)
elseif(bswl .and. ndecodesuccess.ge.2) then
seenb4=.false.
do i=1,nshmem
if( msgreceived .eq. recent_shmsgs(i) ) then
seenb4=.true.
endif
enddo
call update_recent_shmsgs(msgreceived,recent_shmsgs,nshmem)
bflag=seenb4 .and. &
(msgreceived.ne.msglastswl .or. nsnr.gt.nsnrlastswl .or. tsec.lt.tsec0) &
.and. nsnr.gt.-6
if(bflag) then
msglastswl=msgreceived
nsnrlastswl=nsnr
write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
navg,ncorrected,eyeopening,char(0)
endif
endif
999 tsec0=tsec
return
end subroutine mskrtd
subroutine update_recent_shmsgs(message,msgs,nsize)
character*22 msgs(nsize)
character*22 message
logical*1 seen
seen=.false.
do i=1,nsize
if( msgs(i) .eq. message ) seen=.true.
enddo
if( .not. seen ) then
do i=nsize,2,-1
msgs(i)=msgs(i-1)
enddo
msgs(1)=message
endif
return
end subroutine update_recent_shmsgs