diff --git a/lib/qra/qra65/qra65sim.f90 b/lib/qra/qra65/qra65sim.f90 index 299c95445..e91324d27 100644 --- a/lib/qra/qra65/qra65sim.f90 +++ b/lib/qra/qra65/qra65sim.f90 @@ -96,8 +96,8 @@ program qra65sim bandwidth_ratio=2500.0/6000.0 sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb) if(snrdb.gt.90.0) sig=1.0 - write(*,1020) ifile,ntrperiod,f0,csubmode,xsnr,xdt,fspread,msgsent -1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,f6.2,f6.1,1x,a22) + write(*,1020) ifile,ntrperiod,f0,csubmode,snrdb,xdt,fspread,msgsent +1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,f6.2,f6.1,2x,a22) phi=0.d0 dphi=0.d0 k=(xdt+0.5)*12000 !Start audio at t=xdt+0.5 s (TR=15 and 30 s) diff --git a/lib/qra65_decode.f90 b/lib/qra65_decode.f90 index 1f4b0a1f2..0f04565f7 100644 --- a/lib/qra65_decode.f90 +++ b/lib/qra65_decode.f90 @@ -78,7 +78,7 @@ contains baud=12000.0/nsps df1=12000.0/nfft1 -! do i=1,NMAX +! do i=1,12000*ntrperiod ! write(61,3061) i/12000.0,iwave(i)/32767.0 !3061 format(2f12.6) ! enddo @@ -120,24 +120,27 @@ contains call timer('sync_q65',1) ! Downsample to give complex data at 6000 S/s + call timer('down_q65',0) fac=2.0/nfft1 c0=fac*iwave(1:nfft1) call four2a(c0,nfft1,1,-1,1) !Forward c2c FFT c0(nfft2/2+1:nfft2)=0. !Zero the top half c0(0)=0.5*c0(0) call four2a(c0,nfft2,1,1,1) !Inverse c2c FFT - - jpk=(xdt+0.5)*6000 - 384 !### Empirical ### - if(ntrperiod.ge.60) jpk=(xdt+1.0)*6000 - 384 !### TBD ### - if(jpk.lt.0) jpk=0 a=0. a(1)=-(f0 + mode65*baud) !Data tones start mode65 bins higher call twkfreq(c0,c0,ntrperiod*6000,6000.0,a) + call timer('down_q65',1) + + jpk=(xdt+0.5)*6000 - 384 !### Empirical ### + if(ntrperiod.ge.60) jpk=(xdt+1.0)*6000 - 384 !### TBD ??? ### + if(jpk.lt.0) jpk=0 xdt=jpk/6000.0 - 0.5 - LL=64*(mode65+2) NN=63 - call spec_qra65(c0(jpk:),nsps/2,s3,LL,NN) !Compute synchronized symbol spectra + call timer('spec_q65',0) + call spec_qra65(c0(jpk:),nsps/2,s3,LL,NN) !Compute synced symbol spectra + call timer('spec_q65',1) do j=1,63 !Normalize to symbol baseline call pctile(s3(:,j),LL,40,base) @@ -188,7 +191,7 @@ contains irc,qual,ntrperiod,fmid,w50) else snr2=0. - nsnr=-25 + nsnr=-25 !### TEMPORARY? ### call this%callback(nutc,sync,nsnr,xdt,f0,decoded, & irc,qual,ntrperiod,fmid,w50) diff --git a/lib/sync_qra65.f90 b/lib/sync_qra65.f90 index 1a7859cb1..21c155415 100644 --- a/lib/sync_qra65.f90 +++ b/lib/sync_qra65.f90 @@ -6,7 +6,7 @@ subroutine sync_qra65(iwave,nmax,mode65,nsps,nfqso,ntol,xdt,f0,snr1) integer ijpk(2) !Indices i and j at peak of ccf real, allocatable :: s1(:,:) !Symbol spectra, quarter-symbol steps real sync(85) !sync vector - real ccf(-64:64,-15:15) + real ccf(-64:64,-26:107) 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/ @@ -64,24 +64,20 @@ subroutine sync_qra65(iwave,nmax,mode65,nsps,nfqso,ntol,xdt,f0,snr1) !3060 format(i6,f10.3,e12.3) ! enddo + dt4=nsps/(NSTEP*12000.0) !1/4 of symbol duration + j0=0.5/dt4 + if(nsps.ge.7680) j0=1.0/dt4 + ccf=0. ia=min(64,nint(ntol/df)) + lag1=-1.0/dt4 + lag2=4.0/dt4 + 0.9999 - jadd=11 - if(nsps.ge.3600) jadd=7 - if(nsps.ge.7680) jadd=6 - if(nsps.ge.16000) jadd=3 - if(nsps.ge.41472) jadd=1 - dt4=nsps/(NSTEP*12000.0) !1/4 of symbol duration -! print*,'DT range +/-',15*dt4 -! j0=0.5/dt4 -! if(nsps.ge.7680) j0=1.0/dt4 - do i=-ia,ia - do lag=-15,15 + do lag=lag1,lag2 do k=1,85 n=NSTEP*(k-1) + 1 - j=n+lag+jadd + j=n+lag+j0 if(j.ge.1 .and. j.le.jz) then ccf(i,lag)=ccf(i,lag) + sync(k)*s1(i0+i,j) endif @@ -93,13 +89,14 @@ subroutine sync_qra65(iwave,nmax,mode65,nsps,nfqso,ntol,xdt,f0,snr1) ! write(61,3061) i,ccf(i,jpk) !3061 format(i5,e12.3) ! enddo -! do j=-15,15 +! do j=lag1,lag2 ! write(62,3061) j,ccf(ipk,j) ! enddo ijpk=maxloc(ccf) ipk=ijpk(1)-65 - jpk=ijpk(2)-16 +! jpk=ijpk(2)-16 + jpk=ijpk(2)-27 f0=nfqso + ipk*df xdt=jpk*dt4 snr1=maxval(ccf)/22.0 diff --git a/lib/test_qra65.f90 b/lib/test_qra65.f90 index 67af7a720..2ebe08264 100644 --- a/lib/test_qra65.f90 +++ b/lib/test_qra65.f90 @@ -1,16 +1,15 @@ program test_qra65 - character*70 cmd1,cmd2,line + character*71 cmd1,cmd2,line character*22 msg character*8 arg integer nretcode(0:11) - integer fDop logical decok nargs=iargc() - if(nargs.ne.7) then - print*,'Usage: test_qra65 "msg" ndepth freq DT fDop nfiles SNR' - print*,'Example: test_qra65 "K1ABC W9XYZ EN37" 3 1500 0.0 5 100 0' + if(nargs.ne.8) then + print*,'Usage: test_qra65 "msg" ndepth freq DT fDop TRp nfiles SNR' + print*,'Example: test_qra65 "K1ABC W9XYZ EN37" 3 1500 0.0 5.0 60 100 -20' print*,' SNR = 0 to loop over all relevant SNRs' go to 999 endif @@ -24,32 +23,61 @@ program test_qra65 call getarg(5,arg) read(arg,*) fDop call getarg(6,arg) - read(arg,*) nfiles + read(arg,*) ntrperiod call getarg(7,arg) + read(arg,*) nfiles + call getarg(8,arg) read(arg,*) nsnr -! 1 2 3 4 5 6 -! 1234567890123456789012345678901234567890123456789012345678901234' - cmd1='qra65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 100 -10 > junk0' - cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 1 *.wav > junk' - - write(cmd1(10:33),'(a)') '"'//msg//'"' - write(cmd1(37:40),'(i4)') nf0 - write(cmd1(41:45),'(i5)') fDop - write(cmd1(46:50),'(f5.2)') dt - write(cmd1(51:55),'(i5)') nfiles - write(cmd2(32:32),'(i1)') ndepth - call system('rm -f *.wav') - - write(*,1000) (j,j=0,11) - write(12,1000) (j,j=0,11) -1000 format(/'SNR d Dop Sync Dec1 DecN Bad',i5,11i4,' tdec'/83('-')) - ia=-12 - ib=-30 + if(ntrperiod.eq.15) then + nsps=1800 + i50=-21 + else if(ntrperiod.eq.30) then + nsps=3600 + i50=-24 + else if(ntrperiod.eq.60) then + nsps=7680 + i50=-28 + else if(ntrperiod.eq.120) then + nsps=16000 + i50=-31 + else if(ntrperiod.eq.300) then + nsps=41472 + i50=-35 + else + stop 'Invalid TR period' + endif + ia=i50 + 8 + ib=i50 - 5 if(nsnr.ne.0) then ia=nsnr ib=nsnr endif + + baud=12000.0/nsps + tsym=1.0/baud + +! 1 2 3 4 5 6 7 +! 12345678901234567890123456789012345678901234567890123456789012345678901' + cmd1='qra65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 60 100 -10 > junk0' + cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 1 *.wav > junk' + + write(cmd1(10:33),'(a)') '"'//msg//'"' + write(cmd1(37:40),'(i4)') nf0 + write(cmd1(41:45),'(f5.1)') fDop + write(cmd1(46:50),'(f5.2)') dt + write(cmd1(51:54),'(i4)') ntrperiod + write(cmd1(55:59),'(i5)') nfiles + write(cmd2(11:13),'(i3)') ntrperiod + write(cmd2(33:33),'(i1)') ndepth + call system('rm -f *.wav') + + write(*,1000) (j,j=0,11) + write(12,1000) (j,j=0,11) +1000 format(/'SNR d Dop Sync Dec1 DecN Bad',i6,11i4,' tdec dtavg dtrms'/97('-')) + + dterr=3.0*tsym/4.0 + nferr=max(1,nint(0.5*baud)) do nsnr=ia,ib,-1 nsync=0 @@ -57,7 +85,9 @@ program test_qra65 nfalse=0 nretcode=0 navg=0 - write(cmd1(57:59),'(i3)') nsnr + sumxdt=0. + sqxdt=0. + write(cmd1(61:63),'(i3)') nsnr call system(cmd1) call sec0(0,tdec) call system(cmd2) @@ -65,10 +95,11 @@ program test_qra65 open(10,file='junk',status='unknown') n=0 do iline=1,9999 - read(10,'(a70)',end=10) line + read(10,'(a71)',end=10) line if(len(trim(line)).lt.60) cycle read(line(11:20),*) xdt,nf - if(abs(xdt-dt).lt.0.15 .and. abs(nf-nf0).lt.4) nsync=nsync+1 +! if(ntrperiod.eq.60) xdt=xdt-0.5 !### TEMPORARY ### + if(abs(xdt-dt).le.dterr .and. abs(nf-nf0).le.nferr) nsync=nsync+1 read(line(60:),*) irc,iavg if(irc.lt.0) cycle decok=index(line,'W9XYZ').gt.0 @@ -76,6 +107,8 @@ program test_qra65 i=irc if(i.le.11) then ndecodes=ndecodes + 1 + sumxdt=sumxdt + xdt + sqxdt=sqxdt + xdt*xdt navg=navg + 1 else i=mod(i,10) @@ -88,9 +121,17 @@ program test_qra65 endif enddo 10 close(10) - write(*,1100) nsnr,ndepth,fDop,nsync,ndecodes,navg,nfalse,nretcode,tdec/nfiles - write(12,1100) nsnr,ndepth,fDop,nsync,ndecodes,navg,nfalse,nretcode,tdec/nfiles -1100 format(i3,i2,i3,3i5,i4,i6,11i4,f6.2) + xdt_avg=0. + xdt_rms=0. + if(ndecodes.ge.2) then + xdt_avg=sumxdt/ndecodes + xdt_rms=sqxdt/(ndecodes-1) - xdt_avg*xdt_avg + endif + write(*,1100) nsnr,ndepth,fDop,nsync,ndecodes,navg,nfalse,nretcode, & + tdec/nfiles,xdt_avg,xdt_rms + write(12,1100) nsnr,ndepth,fDop,nsync,ndecodes,navg,nfalse,nretcode, & + tdec/nfiles,xdt_avg,xdt_rms +1100 format(i3,i2,f5.1,3i5,i4,i6,11i4,3f6.2) flush(6) flush(12) enddo diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 1cd40b1fe..df2117292 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -6326,23 +6326,30 @@ void MainWindow::on_actionQRA64_triggered() void MainWindow::on_actionQRA65_triggered() { - on_actionFST4_triggered(); +// on_actionFST4_triggered(); m_mode="QRA65"; m_modeTx="QRA65"; ui->actionQRA65->setChecked(true); switch_mode(Modes::QRA65); setup_status_bar(true); + m_nsps=6912; //For symspec only + m_FFTSize = m_nsps / 2; + Q_EMIT FFTSize(m_FFTSize); m_hsymStop=49; ui->sbTR->values ({15, 30, 60, 120, 300}); on_sbTR_valueChanged (ui->sbTR->value()); ui->sbSubmode->setMaximum(3); ui->sbSubmode->setValue(m_nSubMode); m_wideGraph->setMode(m_mode); + m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setPeriod(m_TRperiod,6912); m_wideGraph->setTol(ui->sbFtol->value()); + m_wideGraph->setRxFreq(ui->RxFreqSpinBox->value()); + m_wideGraph->setTxFreq(ui->TxFreqSpinBox->value()); // 0123456789012345678901234567890123 displayWidgets(nWidgets("1111110101101101000100000011000000")); - statusChanged();} + statusChanged(); +} void MainWindow::on_actionISCAT_triggered() {