diff --git a/Configuration.cpp b/Configuration.cpp
index f8e7d52d1..2649991cf 100644
--- a/Configuration.cpp
+++ b/Configuration.cpp
@@ -540,6 +540,7 @@ private:
bool enable_VHF_features_;
bool decode_at_52s_;
bool twoPass_;
+ bool sync1Bit_;
bool MyDx_;
bool CQMyN_;
bool NDxG_;
@@ -619,6 +620,7 @@ bool Configuration::TX_messages () const {return m_->TX_messages_;}
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
bool Configuration::twoPass() const {return m_->twoPass_;}
+bool Configuration::sync1Bit() const {return m_->sync1Bit_;}
bool Configuration::MyDx() const {return m_->MyDx_;}
bool Configuration::CQMyN() const {return m_->CQMyN_;}
bool Configuration::NDxG() const {return m_->NDxG_;}
@@ -1046,6 +1048,7 @@ void Configuration::impl::initialize_models ()
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
ui_->cbTwoPass->setChecked(twoPass_);
+ ui_->cbSync1Bit->setChecked(sync1Bit_);
ui_->cbMyDx->setChecked(MyDx_);
ui_->cbCQMyN->setChecked(CQMyN_);
ui_->cbNDxG->setChecked(NDxG_);
@@ -1275,6 +1278,7 @@ void Configuration::impl::read_settings ()
enable_VHF_features_ = settings_->value("VHFUHF",false).toBool ();
decode_at_52s_ = settings_->value("Decode52",false).toBool ();
twoPass_ = settings_->value("TwoPass",true).toBool ();
+ sync1Bit_ = settings_->value("1BitSync",true).toBool ();
MyDx_ = settings_->value("MyDx",false).toBool ();
CQMyN_ = settings_->value("CQMyN",false).toBool ();
NDxG_ = settings_->value("NDxG",false).toBool ();
@@ -1372,6 +1376,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("VHFUHF", enable_VHF_features_);
settings_->setValue ("Decode52", decode_at_52s_);
settings_->setValue ("TwoPass", twoPass_);
+ settings_->setValue ("Sync1Bit", sync1Bit_);
settings_->setValue ("MyDx", MyDx_);
settings_->setValue ("CQMyN", CQMyN_);
settings_->setValue ("NDxG", NDxG_);
@@ -1758,6 +1763,7 @@ void Configuration::impl::accept ()
enable_VHF_features_ = ui_->enable_VHF_features_check_box->isChecked ();
decode_at_52s_ = ui_->decode_at_52s_check_box->isChecked ();
twoPass_ = ui_->cbTwoPass->isChecked ();
+ sync1Bit_ = ui_->cbSync1Bit->isChecked ();
MyDx_ = ui_->cbMyDx->isChecked ();
CQMyN_ = ui_->cbCQMyN->isChecked ();
NDxG_ = ui_->cbNDxG->isChecked ();
diff --git a/Configuration.hpp b/Configuration.hpp
index 75ae1ce79..e441fa47e 100644
--- a/Configuration.hpp
+++ b/Configuration.hpp
@@ -113,6 +113,7 @@ public:
bool enable_VHF_features () const;
bool decode_at_52s () const;
bool twoPass() const;
+ bool sync1Bit() const;
bool MyDx() const;
bool CQMyN() const;
bool NDxG() const;
diff --git a/Configuration.ui b/Configuration.ui
index 9882996c2..228dbbb50 100644
--- a/Configuration.ui
+++ b/Configuration.ui
@@ -2226,6 +2226,16 @@ Right click for insert and delete options.
+ -
+
+
+ Robust sync
+
+
+ true
+
+
+
-
diff --git a/lib/decoder.f90 b/lib/decoder.f90
index ef001e8d8..513de7398 100644
--- a/lib/decoder.f90
+++ b/lib/decoder.f90
@@ -21,6 +21,8 @@ subroutine decoder(ss,id2,nfsample)
n2pass=ndepth/100000
ndepth=ndepth-n2pass*100000
+ nrobust=ndepth/10000
+ ndepth=ndepth-nrobust*10000
n=ndepth/1000
if(mod(n,2).eq.0) ntrials=10**(n/2)
if(mod(n,2).eq.1) ntrials=3*10**(n/2)
@@ -78,7 +80,7 @@ subroutine decoder(ss,id2,nfsample)
nf2=nfb
call timer('jt65a ',0)
call jt65a(dd,npts65,newdat65,nutc,nf1,nf2,nfqso,ntol65,nsubmode, &
- minsync,nagain,n2pass,ntrials,naggressive,ndepth,ndecoded)
+ minsync,nagain,n2pass,nrobust,ntrials,naggressive,ndepth,ndecoded)
call timer('jt65a ',1)
else if(nmode.eq.9 .or. (nmode.eq.(65+9) .and. ntxmode.eq.9)) then
@@ -97,7 +99,7 @@ subroutine decoder(ss,id2,nfsample)
nf2=nfb
call timer('jt65a ',0)
call jt65a(dd,npts65,newdat65,nutc,nf1,nf2,nfqso,ntol65,nsubmode, &
- minsync,nagain,n2pass,ntrials,naggressive,ndepth,ndecoded)
+ minsync,nagain,n2pass,nrobust,ntrials,naggressive,ndepth,ndecoded)
call timer('jt65a ',1)
else
call timer('decjt9 ',0)
diff --git a/lib/jt65.f90 b/lib/jt65.f90
index c366922cf..b480d58e0 100644
--- a/lib/jt65.f90
+++ b/lib/jt65.f90
@@ -13,10 +13,11 @@ logical :: display_help=.false.,err
character(len=500) optarg
common/tracer/limtrace,lu
equivalence (lenfile,ihdr(2))
- type (option) :: long_options(3) = [ &
+ type (option) :: long_options(4) = [ &
option ('help',.false.,'h','Display this help message',''), &
option ('ntrials',.true.,'n','default=1000',''), &
- option ('single-signal mode',.false.,'s','default=1000','') ]
+ option ('robust sync',.false.,'n','default: disabled',''), &
+ option ('single-signal mode',.false.,'s','default: disabled','') ]
limtrace=0
lu=12
@@ -28,9 +29,10 @@ ntrials=10000
nlow=200
nhigh=4000
n2pass=2
+nrobust=0
do
- call getopt('hn:s',long_options,c,optarg,narglen,nstat,noffset,nremain,err)
+ call getopt('hn:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,err)
if( nstat .ne. 0 ) then
exit
end if
@@ -39,6 +41,8 @@ n2pass=2
display_help = .true.
case ('n')
read (optarg(:narglen), *) ntrials
+ case ('r')
+ nrobust=1
case ('s')
nlow=1250
nhigh=1290
@@ -49,6 +53,7 @@ n2pass=2
nargs=iargc()
if(display_help .or. (nargs.lt.1)) then
print*,'Usage: jt65 [-n ntrials] [-s] file1 [file2 ...]'
+ print*,' -r robust sync'
print*,' -s single-signal mode'
go to 999
endif
@@ -80,7 +85,7 @@ n2pass=2
! write(56) ihdr(1:11)
call jt65a(dd,npts,newdat,nutc,nfa,nfb,nfqso,ntol,nsubmode, &
- minsync,nagain,n2pass,ntrials, naggressive,ndepth,ndecoded)
+ minsync,nagain,n2pass,nrobust,ntrials, naggressive,ndepth,ndecoded)
call timer('jt65a ',1)
enddo
diff --git a/lib/jt65a.f90 b/lib/jt65a.f90
index e00d43caa..127e768d6 100644
--- a/lib/jt65a.f90
+++ b/lib/jt65a.f90
@@ -1,5 +1,5 @@
subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
- minsync,nagain,n2pass,ntrials,naggressive,ndepth,ndecoded)
+ minsync,nagain,n2pass,nrobust,ntrials,naggressive,ndepth,ndecoded)
! Process dd0() data to find and decode JT65 signals.
@@ -7,7 +7,6 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
parameter (NFFT=1000)
real dd0(NZMAX)
real dd(NZMAX)
-! integer*2 id2(NZMAX)
real ss(322,NSZ)
real savg(NSZ)
real a(5)
@@ -17,7 +16,7 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
real dt
real sync
end type candidate
- type(candidate) ca(300)
+ type(candidate) ca(300), car(300)
type decode
real freq
real dt
@@ -31,11 +30,10 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
dd=dd0
ndecoded=0
-
do ipass=1,n2pass ! 2-pass decoding loop
newdat=1
if(ipass.eq.1) then !first-pass parameters
- thresh0=2.5 ! use thresh0=2.0 for -24dB files when using 1-bit sync ccf
+ thresh0=2.5
nsubtract=1
elseif( ipass.eq.2 ) then !second-pass parameters
thresh0=2.5
@@ -54,24 +52,51 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
! nfa=max(200,nfqso-ntol)
! nfb=min(4000,nfqso+ntol)
- ncand=0
- nrobust=0 ! controls use of robust correlation estimator in sync65
- call timer('sync65 ',0)
- call sync65(ss,nfa,nfb,nhsym,ca,ncand,nrobust) !Get a list of JT65 candidates
- call timer('sync65 ',1)
-
-! When AGC threshold is set too low, noise will suddenly quiet when a strong
-! signal starts up. This causes a lot of false syncs, and bogs down the decoder.
-! If 1-bit correlation doesn't tame the resulting false syncs then, as a last
-! resort, drop down to nrials=100.
- if(ncand.ge.50) then
+! OPTION 2 is not used at present. Checkbox in Advanced setup selects nrobust=1
+! nrobust = 0: use only float ccf
+! nrobust = 1: use only robust (1-bit) ccf
+! nrobust = 2: use algorithm below
+! find ncand using float ccf and ncandr using 1-bit ccf
+! if ncand>50, use robust ccf
+! if ncand<25 and ncandr<25, form union of both sets
+! else, use float ccf
+ if( (nrobust.eq.0) .or. (nrobust.eq.2) ) then
ncand=0
- nrobust=1
call timer('sync65 ',0)
- call sync65(ss,nfa,nfb,nhsym,ca,ncand,nrobust) !Get a list of JT65 candidates
+ call sync65(ss,nfa,nfb,nhsym,ca,ncand,0)
call timer('sync65 ',1)
endif
-!write(*,*) 'ncand',ncand
+
+ if( (nrobust.eq.1) .or. (nrobust.eq.2) ) then
+ ncandr=0
+ call timer('sync65 ',0)
+ call sync65(ss,nfa,nfb,nhsym,car,ncandr,1)
+ call timer('sync65 ',1)
+ endif
+ if( (nrobust.eq.1) .or. ((nrobust.eq.2) .and. (ncand.gt.50)) ) then
+ ncand=ncandr
+ do i=1,ncand
+ ca(i)=car(i)
+ enddo
+ elseif(nrobust.eq.2.and.ncand.le.25.and.ncandr.le.25) then
+ do icand=1,ncand ! combine ca and car, without dupes
+ ndupe=0
+ do j=1,ncandr
+ if( abs(ca(icand)%freq-car(j)%freq) .lt. 1.0 ) then
+ ndupe=1
+ endif
+ enddo
+ if( ndupe.eq.0 ) then
+ ncandr=ncandr+1
+ car(ncandr)=ca(icand)
+ endif
+ enddo
+ ncand=ncandr
+ do i=1,ncand
+ ca(i)=car(i)
+ enddo
+ endif
+
nvec=ntrials
if(ncand.gt.75) then
! write(*,*) 'Pass ',ipass,' ncandidates too large ',ncand
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 257462483..1a68e2a7f 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1659,6 +1659,7 @@ void MainWindow::decode() //decode()
jt9com_.nfqso=m_wideGraph->rxFreq();
jt9com_.ndepth=100000 + 1000*m_config.ntrials() + 10*m_config.aggressive() + m_ndepth;
if(m_config.twoPass()) jt9com_.ndepth += 100000;
+ if(m_config.sync1Bit()) jt9com_.ndepth += 10000;
jt9com_.ndiskdat=0;
if(m_diskData) jt9com_.ndiskdat=1;
jt9com_.nfa=m_wideGraph->nStartFreq();