Work in progress... Q65 decoding now works when called as a subroutine.

This commit is contained in:
Joe Taylor 2022-12-09 19:08:35 -05:00
parent ff56d9fa0b
commit e26b2db967
11 changed files with 131 additions and 60 deletions

View File

@ -29,7 +29,7 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
! mygrid=transfer(params%mygrid,mygrid)
! hisgrid=transfer(params%hisgrid,hisgrid)
datetime=' '
my_q65%decoded = 0
ncontest=0
nQSOprogress=0
@ -43,9 +43,6 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
ndepth=2 !Does this make it too slow?
ntrperiod=60
open(17,file=trim(temp_dir)//'/red.dat',status='unknown')
open(14,file=trim(temp_dir)//'/avemsg.txt',status='unknown')
call timer('dec_q65 ',0)
call my_q65%decode(q65_decoded,id2,nqd,nutc,ntrperiod,nsubmode,nfqso, &
ntol,ndepth,nfa,nfb,lclearave,single_decode,lagain,max_drift,lnewdat, &

View File

@ -288,8 +288,8 @@ contains
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
call sec0(1,tdecode)
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
position='append',iostat=ios)
! open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
! position='append',iostat=ios)
if(ios.eq.0) then
! Save decoding parameters to q65_decoded.dat, for later analysis.
write(cmode,'(i3)') ntrperiod
@ -302,10 +302,10 @@ contains
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
tdecode,mycall(1:6),c6,c4,trim(decoded)
close(22)
! write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
! ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
! tdecode,mycall(1:6),c6,c4,trim(decoded)
! close(22)
endif
endif
endif
@ -373,8 +373,8 @@ contains
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
call sec0(1,tdecode)
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
position='append',iostat=ios)
! open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown',&
! position='append',iostat=ios)
if(ios.eq.0) then
! Save decoding parameters to q65_decoded.dat, for later analysis.
write(cmode,'(i3)') ntrperiod
@ -387,10 +387,10 @@ contains
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
tdecode,mycall(1:6),c6,c4,trim(decoded)
close(22)
! write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
! ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
! tdecode,mycall(1:6),c6,c4,trim(decoded)
! close(22)
endif
endif
endif

View File

@ -217,11 +217,9 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
if(i2.eq.-9999 .and. ccf1(-i).ge.0.5*smax) i2=-i
enddo
width=df*(i2-i1)
if(ncw.eq.0) ccf1=0.
call q65_write_red(iz,xdt,ccf2_avg,ccf2)
call q65_write_red(iz,xdt,ccf2_avg,ccf2) !### Need this call for WSJT-X
if(idec.lt.0 .and. (iavg.eq.0 .or. iavg.eq.2)) then
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
endif

View File

@ -43,6 +43,46 @@ extern struct { //This is "common/datcom/..." in Fortran
int junk1; //Used to test extent of copy to shared memory
int junk2;
} datcom_;
extern struct { //This is "common/datcom/..." in Fortran
float d4[4*5760000]; //Raw I/Q data from Linrad
float ss[4*322*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
float savg[4*NFFT]; //Avg spectra at 0,45,90,135 deg pol
double fcenter; //Center freq from Linrad (MHz)
int nutc; //UTC as integer, HHMM
int idphi; //Phase correction for Y pol'n, degrees
int mousedf; //User-selected DF
int mousefqso; //User-selected QSO freq (kHz)
int nagain; //1 ==> decode only at fQSO +/- Tol
int ndepth; //How much hinted decoding to do?
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
int neme; //Hinted decoding tries only for EME calls
int newdat; //1 ==> new data, must do long FFT
int nfa; //Low decode limit (kHz)
int nfb; //High decode limit (kHz)
int nfcal; //Frequency correction, for calibration (Hz)
int nfshift; //Shift of displayed center freq (kHz)
int mcall3; //1 ==> CALL3.TXT has been modified
int ntimeout; //Max for timeouts in Messages and BandMap
int ntol; //+/- decoding range around fQSO (Hz)
int nxant; //1 ==> add 45 deg to measured pol angle
int map65RxLog; //Flags to control log files
int nfsample; //Input sample rate
int nxpol; //1 if using xpol antennas, 0 otherwise
int nmode; //nmode = 10*m_modeQ65 + m_modeJT65
int ndop00; //EME Self Doppler
int nsave; //Number of s3(64,63) spectra saved
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
int nhsym; //Number of available JT65 half-symbols
char mycall[12];
char mygrid[6];
char hiscall[12];
char hisgrid[6];
char datetime[20];
int junk1; //Used to test extent of copy to shared memory
int junk2;
} datcom2_;
}
#endif // COMMONS_H

View File

@ -54,6 +54,7 @@ set (libm65_FSRCS
jt65code.f90
k2grid.f90
lorentzian.f90
m65c.f90
map65a.f90
moon2.f90
moondop.f90

View File

@ -1,20 +1,23 @@
subroutine ftninit(appd)
!subroutine ftninit()
subroutine ftninit
use timer_module, only: timer
use, intrinsic :: iso_c_binding, only: C_NULL_CHAR
use FFTW3
character*(*) appd
! character*(*) appd
character*1 appd
character addpfx*8
character wisfile*256
common/pfxcom/addpfx
appd='.'
addpfx=' '
call pfxdump(appd//'/prefixes.txt')
open(12,file=appd//'/q65w_decodes.txt',status='unknown')
open(13,file=appd//'/map65.log',status='unknown')
open(17,file=appd//'/red.dat',status='unknown')
open(19,file=appd//'/livecq.txt',status='unknown')
open(21,file=appd//'/map65_rx.log',status='unknown',access='append',err=950)
open(26,file=appd//'/tmp26.txt',status='unknown')
! open(21,file=appd//'/map65_rx.log',status='unknown',access='append',err=950)
! open(26,file=appd//'/tmp26.txt',status='unknown')
! Import FFTW wisdom, if available:
iret=fftwf_init_threads() !Initialize FFTW threading

View File

@ -86,7 +86,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
nsum=0
!### Should use AppDir! ###
open(23,file='CALL3.TXT',status='unknown')
! open(23,file='CALL3.TXT',status='unknown')
df=96000.0/NFFT !df = 96000/NFFT = 2.930 Hz
if(nfsample.eq.95238) df=95238.1/NFFT
@ -305,7 +305,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
! Trim the list and produce a sorted index and sizes of groups.
! (Should trimlist remove all but best SNR for given UTC and message content?)
700 call trimlist(sig,km,ftol,indx,nsiz,nz)
700 call trimlist(sig,km,ftol,indx,nsiz,nz)
done(1:km)=.false.
j=0
ilatest=-1
@ -373,27 +373,28 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
cmode='#A'
if(mode65.eq.2) cmode='#B'
if(mode65.eq.4) cmode='#C'
write(26,1014) f0,ndf,ndf0,ndf1,ndf2,dt,npol,nsync1, &
nsync2,nutc,decoded,cp,cmode
1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,2x,a1,3x,a2)
! write(26,1014) f0,ndf,ndf0,ndf1,ndf2,dt,npol,nsync1, &
! nsync2,nutc,decoded,cp,cmode
!1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,2x,a1,3x,a2)
ndecodes=ndecodes+1
write(21,1100) f0,ndf,dt,npol,nsync2,nutc,decoded,cp, &
cmode(1:1),cmode(2:2)
1100 format(f8.3,i5,f5.1,2i4,i5.4,2x,a22,2x,a1,3x,a1,1x,a1)
! write(21,1100) f0,ndf,dt,npol,nsync2,nutc,decoded,cp, &
! cmode(1:1),cmode(2:2)
!1100 format(f8.3,i5,f5.1,2i4,i5.4,2x,a22,2x,a1,3x,a1,1x,a1)
endif
endif
j=j+nsiz(n)
enddo !i=1,km
write(26,1015) nutc
1015 format(37x,i6.4,' ')
call flush(21)
call flush(26)
call display(nkeep,ftol)
! write(26,1015) nutc
!1015 format(37x,i6.4,' ')
! call flush(21)
! call flush(26)
! call display(nkeep,ftol)
ndecdone=2
900 close(23)
900 continue
! close(23)
call flush(12)
ndphi=0
mcall3b=mcall3a

View File

@ -40,10 +40,10 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
save
if(newdat.eq.1) nutc00=-1
open(9,file='wsjtx_dir.txt',status='old')
read(9,'(a)') wsjtx_dir !Establish the working directory
close(9)
! open(9,file='wsjtx_dir.txt',status='old')
! read(9,'(a)') wsjtx_dir !Establish the working directory
! close(9)
if(mycall0(1:1).ne.' ') mycall=mycall0
if(hiscall0(1:1).ne.' ') hiscall=hiscall0
if(hisgrid(1:4).ne.' ') grid4=hisgrid(1:4)
@ -139,10 +139,10 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
nsnr0=-99 !Default snr for no decode
! NB: Frequency of ipk is now shifted to 1000 Hz.
call map65_mmdec(nutc,iwave,nqd,nsubmode,nfa,nfb,1000,ntol, &
newdat,nagain,max_drift,mycall,hiscall,hisgrid)
MHz=fcenter
MHz=fcenter
freq0=MHz + 0.001d0*ikhz
if(nsnr0.gt.-99) then
@ -172,18 +172,18 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
cmode=': '
cmode(2:2)=char(ichar('A') + mode_q65-1)
freq1=freq0 + 0.001d0*(ikhz1-ikhz)
write(26,1014) freq1,ndf,0,0,0,xdt0,npol,0,nsnr0,nutc,msg0(1:22), &
':',cp,cmode
1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,1x,2a1,2x,a2)
! write(26,1014) freq1,ndf,0,0,0,xdt0,npol,0,nsnr0,nutc,msg0(1:22), &
! ':',cp,cmode
!1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,1x,2a1,2x,a2)
! Suppress writing duplicates (same time, decoded message, and frequency)
! to map65_rx.log
if(nutc.ne.nutc00 .or. msg0(1:28).ne.msg00 .or. freq1.ne.freq1_00) then
! Write to file map65_rx.log:
ndecodes=ndecodes+1
write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28), &
cmode(2:2),cq0
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': ',a1,2x,a3)
! write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28), &
! cmode(2:2),cq0
!1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': ',a1,2x,a3)
nutc00=nutc
msg00=msg0(1:28)
freq1_00=freq1
@ -195,9 +195,10 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
1121 format('~',i4.4,f9.3,f7.2,i5,2x,a,i6)
endif
endif
900 close(13)
close(17)
900 continue
! close(13)
! close(17)
call flush(6)
idec=-1
read(cq0(2:2),*) idec

View File

@ -12,11 +12,21 @@
extern "C" {
// Fortran procedures we need
void four2a_ (_Complex float *, int * nfft, int * ndim, int * isign, int * iform, int len);
void _gfortran_set_args(int argc, char *argv[]);
void _gfortran_set_convert(int conv);
void ftninit_(void);
}
int main(int argc, char *argv[])
{
QApplication a {argc, argv};
// Initialize libgfortran:
_gfortran_set_args(argc, argv);
_gfortran_set_convert(0);
ftninit_();
// Override programs executable basename as application name.
a.setApplicationName ("Q65W");
a.setApplicationVersion ("0.1");

View File

@ -180,6 +180,8 @@ MainWindow::MainWindow(QWidget *parent) :
watcher2 = new QFutureWatcher<void>;
connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
connect(&watcher3, SIGNAL(finished()),this,SLOT(decoderFinished()));
// Assign input device and start input thread
soundInThread.setInputDevice(m_paInDevice);
soundInThread.setRate(96000.0);
@ -494,7 +496,7 @@ void MainWindow::dataSink(int k)
n=0;
}
qDebug() << "aa" << ihsym << k << px;
// qDebug() << "aa" << ihsym << k << px;
if(ihsym==302) { //Decode at t=56 s (for Q65 and data from disk)
m_RxState=2;
@ -849,7 +851,16 @@ void MainWindow::diskWriteFinished() //diskWriteFinished
{
// qDebug() << "diskWriteFinished";
}
//Delete ../save/*.tf2
void MainWindow::decoderFinished() //diskWriteFinished
{
m_map65RxLog=0;
m_startAnother=m_loopall;
ui->DecodeButton->setStyleSheet("");
decodeBusy(false);
}
//Delete ../save/*.tf2
void MainWindow::on_actionDelete_all_tf2_files_in_SaveDir_triggered()
{
int i;
@ -1003,7 +1014,8 @@ void MainWindow::decode() //decode()
datcom_.junk1=1234; //Cecck for these values in m65
datcom_.junk2=5678;
char *to = (char*)mem_m65.data();
// char *to = (char*)mem_m65.data();
char *to = (char*) datcom2_.d4;
char *from = (char*) datcom_.d4;
int size=sizeof(datcom_);
if(datcom_.newdat==0) {
@ -1012,14 +1024,17 @@ void MainWindow::decode() //decode()
from += noffset;
size -= noffset;
}
memcpy(to, from, qMin(mem_m65.size(), size-8));
memcpy(to, from, qMin(mem_m65.size(), size-4));
datcom_.nagain=0;
datcom_.ndiskdat=0;
m_map65RxLog=0;
m_call3Modified=false;
QFile lockFile(m_appDir + "/.lock"); // Allow m65 to start
lockFile.remove();
// QFile lockFile(m_appDir + "/.lock"); // Allow m65 to start
// lockFile.remove();
watcher3.setFuture(QtConcurrent::run (std::bind (m65c_)));
decodeBusy(true);
}

View File

@ -42,6 +42,7 @@ public slots:
void dataSink(int k);
void diskDat();
void diskWriteFinished();
void decoderFinished();
void freezeDecode(int n);
void readFromStdout();
void m65_error (QProcess::ProcessError);
@ -173,6 +174,8 @@ private:
QFutureWatcher<void>* watcher1;
QFutureWatcher<void>* watcher2;
QFutureWatcher<void> watcher3; //For decoder
QProcess proc_m65;
QString m_path;
@ -227,6 +230,8 @@ extern "C" {
void astrosub00_ (int* nyear, int* month, int* nday, double* uth, int* nfreq,
const char* mygrid, int* ndop00, int len1);
void m65c_(void);
}
#endif // MAINWINDOW_H