When requested, call the QMAP decoder also at t=30s.

This commit is contained in:
Joe Taylor 2023-12-14 13:37:28 -05:00
parent 1aeaec7a6d
commit 9d5f3858d4
10 changed files with 68 additions and 37 deletions

View File

@ -43,6 +43,7 @@ extern struct { //This is "common/datcom/..." in Fortran
char datetime[20];
int junk1; //Used to test extent of copy to shared memory
int junk2;
bool bAlso30; //Process for 30-second submode as well as 60-second
} datcom_;
extern struct { //This is "common/datcom/..." in Fortran
@ -83,6 +84,7 @@ extern struct { //This is "common/datcom/..." in Fortran
char datetime[20];
int junk1; //Used to test extent of copy to shared memory
int junk2;
bool bAlso30; //Process for 30-second submode as well as 60-second
} datcom2_;
extern struct {

View File

@ -7,6 +7,7 @@ subroutine decode0(dd,ss,savg)
real*8 fcenter
integer offset
integer hist(0:32768)
logical*1 bAlso30
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
character mycall0*12,hiscall0*12,hisgrid0*6
character*60 result
@ -16,7 +17,7 @@ subroutine decode0(dd,ss,savg)
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
ndop00,nsave,max_drift,offset,nhsym,mycall,mygrid, &
hiscall,hisgrid,datetime
hiscall,hisgrid,datetime,junk1,junk2,bAlso30
data neme0/-99/
save
@ -47,7 +48,7 @@ subroutine decode0(dd,ss,savg)
call qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
mousedf,mousefqso,nagain,nfshift,max_drift,offset, &
nfcal,mycall,hiscall,hisgrid,nfsample,nmode,ndepth, &
datetime,ndop00,fselected)
datetime,ndop00,fselected,bAlso30)
call timer('qmapa ',1)
return

View File

@ -1,4 +1,4 @@
subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,bAlso30,cand,ncand)
! Get candidates for Q65 decodes, based on presence of sync tone.
@ -17,6 +17,7 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
real savg0(NFFT),savg(NFFT) !Average spectra over whole Rx sequence
integer ipk1(1) !Peak index of local portion of spectrum
logical sync_ok !True if sync pattern is present
logical*1 bAlso30
data nseg/16/,npct/40/
savg=savg0 !Save the original spectrum
@ -69,8 +70,8 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
if(j.ge.MAX_CANDIDATES) exit
endif
if(.not.bAlso30) cycle
ntrperiod=30
! if(ntrperiod.eq.30) cycle
call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt)
if(sync_ok) then

View File

@ -1 +1 @@
parameter(NJUNK=41)
parameter(NJUNK=42)

View File

@ -120,6 +120,12 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
freq0=MHz + 0.001d0*ikhz
if(nsnr0.gt.-99) then
do i=1,ndecodes !Check for dupes
i1=index(result(i),trim(msg0))
if(i1.ge.1) go to 800
enddo
nq65df=nint(1000*(0.001*k0*df+nkhz_center-48.0+1.000-1.27046-ikhz))-nfcal
nq65df=nq65df + nfreq0 - 1000
ikhz1=ikhz
@ -128,16 +134,16 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
if(ndf.lt.-500) ikhz1=ikhz + (nq65df-500)/1000
ndf=nq65df - 1000*(ikhz1-ikhz)
freq1=freq0 + 0.001d0*(ikhz1-ikhz)
ndecodes=min(ndecodes+1,50)
frx=0.001*k0*df+nkhz_center-48.0+1.0 - 0.001*nfcal
fsked=frx - 0.001*ndop00/2.0 - 0.001*offset
ctmp=csubmode//' '//trim(msg0)
ndecodes=min(ndecodes+1,50)
write(result(ndecodes),1120) nhhmmss,frx,fsked,xdt0,nsnr0,trim(ctmp)
1120 format(i6.6,f9.3,f7.1,f7.2,i5,2x,a)
write(12,1130) datetime1,trim(result(ndecodes)(7:))
1130 format(a13,1x,a)
result(ndecodes)=trim(result(ndecodes))//char(0)
idec=0
800 idec=0
endif
900 flush(12)

View File

@ -12,6 +12,7 @@ subroutine q65c(itimer)
real*8 fcenter
integer nparams0(NJUNK+3),nparams(NJUNK+3)
logical first
logical*1 bAlso30
character*12 mycall,hiscall
character*6 mygrid,hisgrid
character*20 datetime
@ -23,7 +24,7 @@ subroutine q65c(itimer)
ndepth,ndiskdat,neme,newdat,nn1,nn2,nfcal,nfshift, &
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
ndop00,nsave,nn3,nn4,max_nhsym,mycall,mygrid,hiscall,hisgrid, &
datetime,junk1,junk2
datetime,junk1,junk2,bAlso30
equivalence (nparams,fcenter)
data first/.true./
save first
@ -40,10 +41,6 @@ subroutine q65c(itimer)
npatience=1
newdat=1 !Always on ??
! write(*,3001) 'aa',newdat,nagain,nfa,nfb,ntol,fselected
!3001 format(a2,5i6,f10.3)
! write(*,3001) 'bb',newdat,nagain,nfa,nfb,ntol,fselected
call timer('decode0 ',0)
call decode0(dd,ss,savg)
call timer('decode0 ',1)

View File

@ -1,6 +1,7 @@
subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
mousedf,mousefqso,nagain,nfshift,max_drift,offset,nfcal,mycall, &
hiscall,hisgrid,nfsample,nBaseSubmode,ndepth,datetime,ndop00,fselected)
hiscall,hisgrid,nfsample,nBaseSubmode,ndepth,datetime,ndop00, &
fselected,bAlso30)
! Processes timf2 data received from Linrad to find and decode Q65 signals.
@ -22,7 +23,8 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
real dd(2,NSMAX) !I/Q data from Linrad
real ss(400,NFFT) !Symbol spectra
real savg(NFFT) !Average spectrum
real*8 fcenter !Center RF frequency, MHz
real*8 fcenter !Center RF frequency, MHz
logical*1 bAlso30
character mycall*12,hiscall*12,hisgrid*6
type(candidate) :: cand(MAX_CANDIDATES)
character*60 result
@ -42,7 +44,7 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
call timer('get_cand',0)
! Get a list of decoding candidates
call getcand2(ss,savg,nts_q65,nagain,ntol,f0_selected,cand,ncand)
call getcand2(ss,savg,nts_q65,nagain,ntol,f0_selected,bAlso30,cand,ncand)
call timer('get_cand',1)
nwrite_q65=0

View File

@ -245,12 +245,9 @@ void MainWindow::writeSettings()
settings.setValue("KB8RQ",m_kb8rq);
settings.setValue("NB",m_NB);
settings.setValue("NBslider",m_NBslider);
settings.setValue("GainX",(double)m_gainx);
settings.setValue("GainY",(double)m_gainy);
settings.setValue("PhaseX",(double)m_phasex);
settings.setValue("PhaseY",(double)m_phasey);
settings.setValue("MaxDrift",ui->sbMaxDrift->value());
settings.setValue("Offset",ui->sbOffset->value());
settings.setValue("Also30",m_bAlso30);
}
//---------------------------------------------------------- readSettings()
@ -306,11 +303,9 @@ void MainWindow::readSettings()
ui->sbOffset->setValue(settings.value("Offset",1500).toInt());
m_NBslider=settings.value("NBslider",40).toInt();
ui->NBslider->setValue(m_NBslider);
m_gainx=settings.value("GainX",1.0).toFloat();
m_gainy=settings.value("GainY",1.0).toFloat();
m_phasex=settings.value("PhaseX",0.0).toFloat();
m_phasey=settings.value("PhaseY",0.0).toFloat();
m_bAlso30=settings.value("Also30",false).toBool();
ui->actionAlso_Q65_30x->setChecked(m_bAlso30);
on_actionAlso_Q65_30x_toggled(m_bAlso30);
if(!ui->actionLinrad->isChecked() && !ui->actionCuteSDR->isChecked() &&
!ui->actionAFMHot->isChecked() && !ui->actionBlue->isChecked()) {
on_actionLinrad_triggered();
@ -351,6 +346,7 @@ void MainWindow::dataSink(int k)
if(!m_fs96000) nfsample=95238;
symspec_(&k, &ndiskdat, &nb, &m_NBslider, &nfsample,
&px, s, &nkhz, &ihsym, &nzap, &slimit, lstrong);
m_ihsym=ihsym;
int nsec=QDateTime::currentSecsSinceEpoch();
if(nsec==nsec0) {
@ -406,10 +402,13 @@ void MainWindow::dataSink(int k)
n=0;
}
bool bCallDecoder=false;
if(ihsym < m_hsymStop) m_decode_called=false;
if(ihsym==m_hsymStop and !m_decode_called) bCallDecoder=true; //Decode at t=58.5 s
if(m_bAlso30 and (ihsym==200)) bCallDecoder=true;
if(ihsym >= m_hsymStop and !m_decode_called) { //Decode at t=56 s (for Q65 and data from disk)
m_decode_called=true;
if(bCallDecoder) {
if(ihsym==m_hsymStop) m_decode_called=true;
datcom_.nagain=0;
datcom_.nhsym=ihsym;
QDateTime t = QDateTime::currentDateTimeUtc();
@ -714,9 +713,13 @@ void MainWindow::diskDat() //diskDat()
hsym=0.15*96000.0; //Samples per Q65-30x half-symbol or Q65-60x quarter-symbol
for(int i=0; i<400; i++) { // Do the half-symbol FFTs
int k = i*hsym + 0.5;
m_ihsym=k;
if(k > 60*96000) break;
dataSink(k);
qApp->processEvents(); // Allow the waterfall to update
while(m_decoderBusy) {
qApp->processEvents(); // Wait for an early decode to finish
}
}
}
@ -882,6 +885,7 @@ void MainWindow::decode() //decode()
}
datcom_.junk1=1234; //Check for these values in m65
datcom_.junk2=5678;
datcom_.bAlso30=m_bAlso30;
char *to = (char*) datcom2_.d4;
char *from = (char*) datcom_.d4;
@ -890,10 +894,12 @@ void MainWindow::decode() //decode()
datcom_.ndiskdat=0;
m_call3Modified=false;
decodes_.ndecodes=0;
if(!m_bAlso30 or (m_bAlso30 and (m_ihsym==200))) {
decodes_.ndecodes=0; //Start the decode cycle with a clean slate
m_fetched=0;
}
decodes_.ncand=0;
decodes_.nQDecoderDone=0;
m_fetched=0;
int itimer=0;
m_decoder_start_time=QDateTime::currentDateTimeUtc();
watcher3.setFuture(QtConcurrent::run (std::bind (q65c_, &itimer)));
@ -965,6 +971,7 @@ void MainWindow::guiUpdate()
if(t.indexOf(m_myCall)>10 and m_myCallColor==2) f.setBackground(QBrush(Qt::green));
if(t.indexOf(m_myCall)>10 and m_myCallColor==3) f.setBackground(QBrush(Qt::cyan));
cursor.setBlockFormat(f);
// qDebug() << "aa" << m_nline << m_decoderBusy << t.trimmed();
}
}
@ -1102,3 +1109,9 @@ void MainWindow::on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered()
{
QDesktopServices::openUrl (QUrl {"https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf"});
}
void MainWindow::on_actionAlso_Q65_30x_toggled(bool b)
{
m_bAlso30=b;
}

View File

@ -82,6 +82,7 @@ private slots:
void on_actionQ65E_triggered();
void on_actionQuick_Start_Guide_to_Q65_triggered();
void on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered();
void on_actionAlso_Q65_30x_toggled(bool b);
private:
Ui::MainWindow *ui;
@ -119,6 +120,7 @@ private:
qint32 m_nDoubleClicked=0;
qint32 m_nline=0;
qint32 m_WSJTX_TRperiod=0;
qint32 m_ihsym;
double m_fAdd;
double m_xavg;
@ -136,11 +138,8 @@ private:
bool m_NB;
bool m_fs96000;
bool m_decode_called=false;
bool m_bAlso30=false;
float m_gainx;
float m_gainy;
float m_phasex;
float m_phasey;
float m_pctZap;
int m_myCallColor;

View File

@ -482,6 +482,8 @@ p, li { white-space: pre-wrap; }
<addaction name="actionQ65C"/>
<addaction name="actionQ65D"/>
<addaction name="actionQ65E"/>
<addaction name="separator"/>
<addaction name="actionAlso_Q65_30x"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
@ -759,7 +761,7 @@ p, li { white-space: pre-wrap; }
<bool>true</bool>
</property>
<property name="text">
<string>Q65A</string>
<string>Q65-60A</string>
</property>
</action>
<action name="actionQ65B">
@ -767,7 +769,7 @@ p, li { white-space: pre-wrap; }
<bool>true</bool>
</property>
<property name="text">
<string>Q65B</string>
<string>Q65-60B</string>
</property>
</action>
<action name="actionQ65C">
@ -778,7 +780,7 @@ p, li { white-space: pre-wrap; }
<bool>true</bool>
</property>
<property name="text">
<string>Q65C</string>
<string>Q65-60C</string>
</property>
</action>
<action name="actionQ65D">
@ -786,7 +788,7 @@ p, li { white-space: pre-wrap; }
<bool>true</bool>
</property>
<property name="text">
<string>Q65D</string>
<string>Q65-60D</string>
</property>
</action>
<action name="actionQ65E">
@ -794,7 +796,7 @@ p, li { white-space: pre-wrap; }
<bool>true</bool>
</property>
<property name="text">
<string>Q65E</string>
<string>Q65-60E</string>
</property>
</action>
<action name="actionQSG_Q65">
@ -843,6 +845,14 @@ p, li { white-space: pre-wrap; }
<string>Continuous Waterfall</string>
</property>
</action>
<action name="actionAlso_Q65_30x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Also Q65-30x</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>