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

View File

@ -7,6 +7,7 @@ subroutine decode0(dd,ss,savg)
real*8 fcenter real*8 fcenter
integer offset integer offset
integer hist(0:32768) integer hist(0:32768)
logical*1 bAlso30
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20 character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
character mycall0*12,hiscall0*12,hisgrid0*6 character mycall0*12,hiscall0*12,hisgrid0*6
character*60 result character*60 result
@ -16,7 +17,7 @@ subroutine decode0(dd,ss,savg)
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, & ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, & mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
ndop00,nsave,max_drift,offset,nhsym,mycall,mygrid, & ndop00,nsave,max_drift,offset,nhsym,mycall,mygrid, &
hiscall,hisgrid,datetime hiscall,hisgrid,datetime,junk1,junk2,bAlso30
data neme0/-99/ data neme0/-99/
save save
@ -47,7 +48,7 @@ subroutine decode0(dd,ss,savg)
call qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, & call qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
mousedf,mousefqso,nagain,nfshift,max_drift,offset, & mousedf,mousefqso,nagain,nfshift,max_drift,offset, &
nfcal,mycall,hiscall,hisgrid,nfsample,nmode,ndepth, & nfcal,mycall,hiscall,hisgrid,nfsample,nmode,ndepth, &
datetime,ndop00,fselected) datetime,ndop00,fselected,bAlso30)
call timer('qmapa ',1) call timer('qmapa ',1)
return 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. ! 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 real savg0(NFFT),savg(NFFT) !Average spectra over whole Rx sequence
integer ipk1(1) !Peak index of local portion of spectrum integer ipk1(1) !Peak index of local portion of spectrum
logical sync_ok !True if sync pattern is present logical sync_ok !True if sync pattern is present
logical*1 bAlso30
data nseg/16/,npct/40/ data nseg/16/,npct/40/
savg=savg0 !Save the original spectrum 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 if(j.ge.MAX_CANDIDATES) exit
endif endif
if(.not.bAlso30) cycle
ntrperiod=30 ntrperiod=30
! if(ntrperiod.eq.30) cycle
call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt) call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt)
if(sync_ok) then 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 freq0=MHz + 0.001d0*ikhz
if(nsnr0.gt.-99) then 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=nint(1000*(0.001*k0*df+nkhz_center-48.0+1.000-1.27046-ikhz))-nfcal
nq65df=nq65df + nfreq0 - 1000 nq65df=nq65df + nfreq0 - 1000
ikhz1=ikhz 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 if(ndf.lt.-500) ikhz1=ikhz + (nq65df-500)/1000
ndf=nq65df - 1000*(ikhz1-ikhz) ndf=nq65df - 1000*(ikhz1-ikhz)
freq1=freq0 + 0.001d0*(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 frx=0.001*k0*df+nkhz_center-48.0+1.0 - 0.001*nfcal
fsked=frx - 0.001*ndop00/2.0 - 0.001*offset fsked=frx - 0.001*ndop00/2.0 - 0.001*offset
ctmp=csubmode//' '//trim(msg0) ctmp=csubmode//' '//trim(msg0)
ndecodes=min(ndecodes+1,50)
write(result(ndecodes),1120) nhhmmss,frx,fsked,xdt0,nsnr0,trim(ctmp) write(result(ndecodes),1120) nhhmmss,frx,fsked,xdt0,nsnr0,trim(ctmp)
1120 format(i6.6,f9.3,f7.1,f7.2,i5,2x,a) 1120 format(i6.6,f9.3,f7.1,f7.2,i5,2x,a)
write(12,1130) datetime1,trim(result(ndecodes)(7:)) write(12,1130) datetime1,trim(result(ndecodes)(7:))
1130 format(a13,1x,a) 1130 format(a13,1x,a)
result(ndecodes)=trim(result(ndecodes))//char(0) result(ndecodes)=trim(result(ndecodes))//char(0)
idec=0 800 idec=0
endif endif
900 flush(12) 900 flush(12)

View File

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

View File

@ -1,6 +1,7 @@
subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, & subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
mousedf,mousefqso,nagain,nfshift,max_drift,offset,nfcal,mycall, & 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. ! 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 dd(2,NSMAX) !I/Q data from Linrad
real ss(400,NFFT) !Symbol spectra real ss(400,NFFT) !Symbol spectra
real savg(NFFT) !Average spectrum 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 character mycall*12,hiscall*12,hisgrid*6
type(candidate) :: cand(MAX_CANDIDATES) type(candidate) :: cand(MAX_CANDIDATES)
character*60 result character*60 result
@ -42,7 +44,7 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
call timer('get_cand',0) call timer('get_cand',0)
! Get a list of decoding candidates ! 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) call timer('get_cand',1)
nwrite_q65=0 nwrite_q65=0

View File

@ -245,12 +245,9 @@ void MainWindow::writeSettings()
settings.setValue("KB8RQ",m_kb8rq); settings.setValue("KB8RQ",m_kb8rq);
settings.setValue("NB",m_NB); settings.setValue("NB",m_NB);
settings.setValue("NBslider",m_NBslider); 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("MaxDrift",ui->sbMaxDrift->value());
settings.setValue("Offset",ui->sbOffset->value()); settings.setValue("Offset",ui->sbOffset->value());
settings.setValue("Also30",m_bAlso30);
} }
//---------------------------------------------------------- readSettings() //---------------------------------------------------------- readSettings()
@ -306,11 +303,9 @@ void MainWindow::readSettings()
ui->sbOffset->setValue(settings.value("Offset",1500).toInt()); ui->sbOffset->setValue(settings.value("Offset",1500).toInt());
m_NBslider=settings.value("NBslider",40).toInt(); m_NBslider=settings.value("NBslider",40).toInt();
ui->NBslider->setValue(m_NBslider); ui->NBslider->setValue(m_NBslider);
m_gainx=settings.value("GainX",1.0).toFloat(); m_bAlso30=settings.value("Also30",false).toBool();
m_gainy=settings.value("GainY",1.0).toFloat(); ui->actionAlso_Q65_30x->setChecked(m_bAlso30);
m_phasex=settings.value("PhaseX",0.0).toFloat(); on_actionAlso_Q65_30x_toggled(m_bAlso30);
m_phasey=settings.value("PhaseY",0.0).toFloat();
if(!ui->actionLinrad->isChecked() && !ui->actionCuteSDR->isChecked() && if(!ui->actionLinrad->isChecked() && !ui->actionCuteSDR->isChecked() &&
!ui->actionAFMHot->isChecked() && !ui->actionBlue->isChecked()) { !ui->actionAFMHot->isChecked() && !ui->actionBlue->isChecked()) {
on_actionLinrad_triggered(); on_actionLinrad_triggered();
@ -351,6 +346,7 @@ void MainWindow::dataSink(int k)
if(!m_fs96000) nfsample=95238; if(!m_fs96000) nfsample=95238;
symspec_(&k, &ndiskdat, &nb, &m_NBslider, &nfsample, symspec_(&k, &ndiskdat, &nb, &m_NBslider, &nfsample,
&px, s, &nkhz, &ihsym, &nzap, &slimit, lstrong); &px, s, &nkhz, &ihsym, &nzap, &slimit, lstrong);
m_ihsym=ihsym;
int nsec=QDateTime::currentSecsSinceEpoch(); int nsec=QDateTime::currentSecsSinceEpoch();
if(nsec==nsec0) { if(nsec==nsec0) {
@ -406,10 +402,13 @@ void MainWindow::dataSink(int k)
n=0; n=0;
} }
bool bCallDecoder=false;
if(ihsym < m_hsymStop) m_decode_called=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) if(bCallDecoder) {
m_decode_called=true; if(ihsym==m_hsymStop) m_decode_called=true;
datcom_.nagain=0; datcom_.nagain=0;
datcom_.nhsym=ihsym; datcom_.nhsym=ihsym;
QDateTime t = QDateTime::currentDateTimeUtc(); 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 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 for(int i=0; i<400; i++) { // Do the half-symbol FFTs
int k = i*hsym + 0.5; int k = i*hsym + 0.5;
m_ihsym=k;
if(k > 60*96000) break; if(k > 60*96000) break;
dataSink(k); dataSink(k);
qApp->processEvents(); // Allow the waterfall to update 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_.junk1=1234; //Check for these values in m65
datcom_.junk2=5678; datcom_.junk2=5678;
datcom_.bAlso30=m_bAlso30;
char *to = (char*) datcom2_.d4; char *to = (char*) datcom2_.d4;
char *from = (char*) datcom_.d4; char *from = (char*) datcom_.d4;
@ -890,10 +894,12 @@ void MainWindow::decode() //decode()
datcom_.ndiskdat=0; datcom_.ndiskdat=0;
m_call3Modified=false; 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_.ncand=0;
decodes_.nQDecoderDone=0; decodes_.nQDecoderDone=0;
m_fetched=0;
int itimer=0; int itimer=0;
m_decoder_start_time=QDateTime::currentDateTimeUtc(); m_decoder_start_time=QDateTime::currentDateTimeUtc();
watcher3.setFuture(QtConcurrent::run (std::bind (q65c_, &itimer))); 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==2) f.setBackground(QBrush(Qt::green));
if(t.indexOf(m_myCall)>10 and m_myCallColor==3) f.setBackground(QBrush(Qt::cyan)); if(t.indexOf(m_myCall)>10 and m_myCallColor==3) f.setBackground(QBrush(Qt::cyan));
cursor.setBlockFormat(f); 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"}); 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_actionQ65E_triggered();
void on_actionQuick_Start_Guide_to_Q65_triggered(); void on_actionQuick_Start_Guide_to_Q65_triggered();
void on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered(); void on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered();
void on_actionAlso_Q65_30x_toggled(bool b);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
@ -119,6 +120,7 @@ private:
qint32 m_nDoubleClicked=0; qint32 m_nDoubleClicked=0;
qint32 m_nline=0; qint32 m_nline=0;
qint32 m_WSJTX_TRperiod=0; qint32 m_WSJTX_TRperiod=0;
qint32 m_ihsym;
double m_fAdd; double m_fAdd;
double m_xavg; double m_xavg;
@ -136,11 +138,8 @@ private:
bool m_NB; bool m_NB;
bool m_fs96000; bool m_fs96000;
bool m_decode_called=false; bool m_decode_called=false;
bool m_bAlso30=false;
float m_gainx;
float m_gainy;
float m_phasex;
float m_phasey;
float m_pctZap; float m_pctZap;
int m_myCallColor; int m_myCallColor;

View File

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