From c5a0de621016ccf1d04770aefab3b35f1a7174d2 Mon Sep 17 00:00:00 2001
From: Joe Taylor <joe@princeton.edu>
Date: Wed, 23 Dec 2020 09:47:11 -0500
Subject: [PATCH] Partial implementation of Q65 message averaging.

---
 lib/q65_decode.f90 |  2 +-
 lib/q65_sync.f90   | 36 ++++++++++++++++++++++++++++++++----
 lib/test_q65.f90   |  4 ++++
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/lib/q65_decode.f90 b/lib/q65_decode.f90
index 7df4185f0..17557cd39 100644
--- a/lib/q65_decode.f90
+++ b/lib/q65_decode.f90
@@ -96,7 +96,7 @@ contains
     call q65_sync(nutc,iwave,ntrperiod*12000,mode65,codewords,ncw,nsps,   &
          nfqso,ntol,emedelay,xdt,f0,snr1,width,dat4,snr2,id1)
     call timer('sync_q65',1)
-    if(id1.eq.1) then
+    if(id1.eq.1 .or. id1.ge.12) then
        xdt1=xdt
        f1=f0
        go to 100
diff --git a/lib/q65_sync.f90 b/lib/q65_sync.f90
index 834059fa1..741436b55 100644
--- a/lib/q65_sync.f90
+++ b/lib/q65_sync.f90
@@ -24,17 +24,19 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
   integer dat4(13)
   integer ijpk(2)
   logical unpk77_success
+  logical lavg
   character*77 c77,decoded*37
   real, allocatable :: s1(:,:)           !Symbol spectra, 1/8-symbol steps
   real, allocatable :: s3(:,:)           !Data-symbol energies s3(LL,63)
+  real, allocatable,save :: s3avg(:,:)   !Averaged data-symbol energies
   real, allocatable :: ccf(:,:)          !CCF(freq,lag)
   real, allocatable :: ccf1(:)           !CCF(freq) at best lag
   real s3prob(0:63,63)                   !Symbol-value probabilities
   real sync(85)                          !sync vector
   complex, allocatable :: c0(:)          !Complex spectrum of symbol
   data isync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
-  data sync(1)/99.0/
-  save sync
+  data sync(1)/99.0/,LL0/-1/
+  save sync,navg,LL0
 
   snr1=0.
   id1=0
@@ -54,6 +56,12 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
 
   allocate(s1(iz,jz))
   allocate(s3(-64:LL-65,63))
+  if(LL.ne.LL0) then
+     if(allocated(s3avg)) deallocate(s3avg)
+     allocate(s3avg(-64:LL-65,63))
+     navg=0
+     LL0=LL
+  endif
   allocate(c0(0:nfft-1))
   allocate(ccf(-ia2:ia2,-53:214))
   allocate(ccf1(-ia2:ia2))
@@ -63,6 +71,8 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
      do k=1,22
         sync(isync(k))=1.0               !Sync tone ON
      enddo
+     s3avg=0.
+     navg=0
   endif
 
   fac=1/32767.0
@@ -175,7 +185,9 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
   baud=12000.0/nsps
   ibwa=1.8*log(baud*mode_q65) + 2
   ibwb=min(10,ibwa+4)
-  do ibw=ibwa,ibwb
+  lavg=.false.
+
+10 do ibw=ibwa,ibwb
      b90=1.72**ibw
      call q65_intrinsics_ff(s3,nsubmode,b90/baud,nFadingModel,s3prob)
      call q65_dec_fullaplist(s3,s3prob,codewords,ncw,esnodb,dat4,plog,irc)
@@ -196,9 +208,9 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
         smax=maxval(ccf1)
         if(smax.gt.10.0) ccf1=10.0*ccf1/smax
         go to 200
-!        go to 900
      endif
   enddo
+  if(lavg) go to 900
 
 !######################################################################
 ! Establish xdt, f0, and snr1 using sync symbols (and perhaps some AP symbols)
@@ -241,6 +253,7 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
   if(snr1.gt.10.0) ccf1=(10.0/snr1)*ccf1
 
 200 smax=maxval(ccf1)
+  if(lavg) id1=10+navg                    !This is an average decode
   i1=-9999
   i2=-9999
   do i=-ia,ia
@@ -254,6 +267,21 @@ subroutine q65_sync(nutc,iwave,nmax,mode_q65,codewords,ncw,nsps,nfqso,ntol, &
   enddo
   close(17)
   width=df*(i2-i1)
+  if(id1.ge.1) then
+     navg=0
+     s3avg=0.
+     if(lavg) go to 900
+  elseif(snr1.ge.0.0) then
+     s3avg=s3avg+s3
+     navg=navg+1
+     write(71,3071) nutc,navg,xdt,f0,snr1
+3071 format(2i5,3f10.2)
+     if(navg.ge.2) then
+        s3=s3avg/navg
+        lavg=.true.
+        go to 10
+     endif
+  endif
 
 900 return
 end subroutine q65_sync
diff --git a/lib/test_q65.f90 b/lib/test_q65.f90
index f614d2703..49a17c678 100644
--- a/lib/test_q65.f90
+++ b/lib/test_q65.f90
@@ -139,6 +139,10 @@ program test_q65
         if(ntrperiod.le.30) i0=25
         if(line(i0:i0).ne.' ') read(line(60:),*) idec
         if(idec.lt.0) cycle
+        if(idec.ge.12) then
+           iavg=idec-10
+           idec=1
+        endif
         if(decok) then
            ndecn=ndecn + 1
            if(iavg.le.1) ndec1=ndec1 + 1