diff --git a/lib/ft2/ft2.f90 b/lib/ft2/ft2.f90 index c77de142f..92280c4bb 100644 --- a/lib/ft2/ft2.f90 +++ b/lib/ft2/ft2.f90 @@ -26,12 +26,13 @@ program ft2 call padevsub(idevin,idevout) if(idevin.ne.ndevin .or. idevout.ne.ndevout) allok=.false. i1=0 -! i1=ptt(nport,1,1,iptt) + i1=ptt(nport,1,0,iptt) if(i1.lt.0 .and. nport.ne.0) allok=.false. if(.not.allok) then write(*,"('Please fix setup error(s) and restart.')") go to 999 endif + open(12,file='all_ft2.txt',status='unknown',position='append') nright=1 iwrite=0 @@ -45,6 +46,11 @@ program ft2 tx_once=.false. snrdb=99.0 txmsg='CQ K1JT FN20' + ltx=.false. + lrx=.false. + autoseq=.false. + QSO_in_progress=.false. + ntxed=0 nargs=iargc() if(nargs.eq.3) then @@ -54,8 +60,8 @@ program ft2 call getarg(3,arg) read(arg,*) snrdb tx_once=.true. - call ft2_iwave(txmsg,f0,snrdb,iwave) - nTxOK=1 + ftx=1500.0 + call transmit(-1,ftx,iptt) endif ! Start the audio streams @@ -70,38 +76,34 @@ program ft2 subroutine update(total_time,ic1,ic2) real*8 total_time - integer*8 count00,count0,count1,clkfreq + integer*8 count0,count1,clkfreq integer ptt integer*2 id(30000) - logical transmitted - character*30 line - character cdate*8,ctime*10,cdatetime*17 + logical transmitted,level + character*70 line + character cdatetime*17 include 'gcom1.f90' - data nt0/-1/,transmitted/.false./,snr/-99.0/,count00/-1/ - save nt0,transmitted,snr,count00,iptt + data nt0/-1/,transmitted/.false./,snr/-99.0/ + data level/.false./ + save nt0,transmitted,level,snr,iptt if(ic1.ne.0 .or. ic2.ne.0) then - if(ic1.eq.27 .and. ic2.eq.0) ngo=0 !ESC + if(ic1.eq.27 .and. ic2.eq.0) ngo=0 !ESC if(nTxOK.eq.0 .and. ntransmitting.eq.0) then - nd=0 - if(ic1.eq.0 .and. ic2.eq.59) nd=1 !F1 - if(ic1.eq.0 .and. ic2.eq.60) nd=2 !F2 - if(ic1.eq.0 .and. ic2.eq.61) nd=3 !F3 - if(ic1.eq.0 .and. ic2.eq.62) nd=4 !F4 - if(ic1.eq.0 .and. ic2.eq.63) nd=5 !F5 - if(nd.gt.0) then - i1=ptt(nport,1,1,iptt) - ntxok=1 - if(nd.eq.1) txmsg='CQ K1JT FN20' - if(nd.eq.2) txmsg='K9AN K1JT 559 NJ' - if(nd.eq.3) txmsg='K9AN K1JT R 559 NJ' - if(nd.eq.4) txmsg='K9AN K1JT RR73' - if(nd.eq.5) txmsg='TNX STEVE 73' - call ft2_iwave(txmsg,1500.0,99.0,iwave) - print*,'Tx: ',txmsg + nfunc=0 + if(ic1.eq.0 .and. ic2.eq.59) nfunc=1 !F1 + if(ic1.eq.0 .and. ic2.eq.60) nfunc=2 !F2 + if(ic1.eq.0 .and. ic2.eq.61) nfunc=3 !F3 + if(ic1.eq.0 .and. ic2.eq.62) nfunc=4 !F4 + if(ic1.eq.0 .and. ic2.eq.63) nfunc=5 !F5 + if(nfunc.eq.1 .or. (nfunc.ge.2 .and. hiscall.ne.' ')) then + ftx=1500.0 + call transmit(nfunc,ftx,iptt) endif endif if(ic1.eq.13 .and. ic2.eq.0) hiscall=hiscall_next + if(ic1.eq.97 .and. ic2.eq.0) autoseq=.not.autoseq + if(ic1.eq.108 .and. ic2.eq.0) level=.not.level endif if(ntransmitting.eq.1) transmitted=.true. @@ -114,17 +116,30 @@ subroutine update(total_time,ic1,ic2) nt=2*total_time if(nt.gt.nt0 .or. ic1.ne.0 .or. ic2.ne.0) then - k=iwrite-6000 - if(k.lt.1) k=k+NRING - sq=0. - do i=1,6000 - k=k+1 - if(k.gt.NRING) k=k-NRING - x=y1(k) - sq=sq + x*x - enddo - sigdb=0. - if(sq.gt.0.0) sigdb=db(sq/6000.0) + if(level) then +! Measure and display the average level of signal plus noise in past 0.5 s + k=iwrite-6000 + if(k.lt.1) k=k+NRING + sq=0. + do i=1,6000 + k=k+1 + if(k.gt.NRING) k=k-NRING + x=y1(k) + sq=sq + x*x + enddo + sigdb=0. + if(sq.gt.0.0) sigdb=db(sq/6000.0) + n=sigdb + if(n.lt.1) n=1 + if(n.gt.70) n=70 + line=' ' + line(n:n)='*' + write(*,1030) sigdb,ntxed,autoseq,QSO_in_progress,(line(i:i),i=1,n) +1030 format(f4.1,i3,2L2,1x,70a1) +! write(*,1020) nt,total_time,iwrite,itx,ntxok,ntransmitting,ndecodes, & +! snr,sigdb,line +!1020 format(i6,f9.3,i10,i6,3i3,f6.0,f6.1,1x,a30) + endif k=iwrite-30000 if(k.lt.1) k=k+NRING do i=1,30000 @@ -136,27 +151,77 @@ subroutine update(total_time,ic1,ic2) nfqso=1500 ndecodes=0 if(maxval(abs(id)).gt.0) then - call date_and_time(cdate,ctime) - cdatetime=cdate(3:8)//'_'//ctime call system_clock(count0,clkfreq) - call ft2_decode(cdatetime,nfqso,id,ndecodes) + nrx=-1 + call ft2_decode(cdatetime(),nfqso,id,ndecodes,mycall,hiscall,nrx) call system_clock(count1,clkfreq) - tdecode=float(count1-count0)/float(clkfreq) - if(count00.lt.0) count00=count0 - trun=float(count1-count00)/float(clkfreq) +! tdecode=float(count1-count0)/float(clkfreq) +! write(*,3001) trun +!3001 format(f10.3) + + if(autoseq .and.nrx.eq.2) QSO_in_progress=.true. + if(autoseq .and. QSO_in_progress .and. nrx.ge.1 .and. nrx.le.4) then + lrx(nrx)=.true. + ftx=1500.0 + if(ntxed.eq.1) then + if(nrx.eq.2) then + call transmit(3,ftx,iptt) + else + call transmit(1,ftx,iptt) + endif + endif + if(ntxed.eq.2) then + if(nrx.eq.3) then + call transmit(4,ftx,iptt) + QSO_in_progress=.false. + else + call transmit(2,ftx,iptt) + endif + endif + if(ntxed.eq.3) then + if(nrx.eq.4) then + QSO_in_progress=.false. + else + call transmit(3,ftx,iptt) + endif + endif + endif endif - n=2*sigdb-30.0 - if(n.lt.1) n=1 - if(n.gt.30) n=30 - line=' ' - line(n:n)='*' -! write(*,1010) nt,total_time,iwrite,itx,ntxok,ntransmitting,ndecodes, & -! snr,sigdb,line -!1010 format(i6,f9.3,i10,i6,3i3,f6.0,f6.1,1x,a30) nt0=nt - max1=0 - max2=0 endif return end subroutine update + +character*17 function cdatetime() + character cdate*8,ctime*10 + call date_and_time(cdate,ctime) + cdatetime=cdate(3:8)//'_'//ctime + return +end function cdatetime + +subroutine transmit(nfunc,ftx,iptt) + include 'gcom1.f90' + character*17 cdatetime + integer ptt + + if(nfunc.eq.1) txmsg='CQ '//trim(mycall)//' '//mygrid + if(nfunc.eq.2) txmsg=trim(hiscall)//' '//trim(mycall)// & + ' 559 '//trim(exch) + if(nfunc.eq.3) txmsg=trim(hiscall)//' '//trim(mycall)// & + ' R 559 '//trim(exch) + if(nfunc.eq.4) txmsg=trim(hiscall)//' '//trim(mycall)//' RR73' + if(nfunc.eq.5) txmsg='TNX 73 GL' + call ft2_iwave(txmsg,ftx,99.0,iwave) + i1=ptt(nport,1,1,iptt) + ntxok=1 + n=len(trim(txmsg)) + write(*,1010) cdatetime(),0,0.0,nint(ftx),(txmsg(i:i),i=1,n) + write(12,1010) cdatetime(),0,0.0,nint(ftx),(txmsg(i:i),i=1,n) +1010 format(a17,' Tx',i4,f6.2,i6,2x,37a1) + if(nfunc.ge.1 .and. nfunc.le.4) ntxed=nfunc + if(nfunc.ge.1 .and. nfunc.le.5) ltx(nfunc)=.true. + if(nfunc.eq.2 .or. nfunc.eq.3) QSO_in_progress=.true. + + return +end subroutine transmit diff --git a/lib/ft2/ft2_decode.f90 b/lib/ft2/ft2_decode.f90 index 74cab3ee4..560732570 100644 --- a/lib/ft2/ft2_decode.f90 +++ b/lib/ft2/ft2_decode.f90 @@ -1,4 +1,4 @@ -subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) +subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes,mycall,hiscall,nrx) use crc use packjt77 @@ -7,6 +7,7 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) character*37 decodes(100) character*120 data_dir character*17 cdatetime + character*6 mycall,hiscall complex c2(0:NMAX/16-1) !Complex waveform complex cb(0:NMAX/16-1) complex cd(0:144*10-1) !Complex waveform @@ -66,7 +67,6 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) ndecodes=0 do icand=1,ncand f0=candidate(1,icand) - xsnr=1.0 if( f0.le.375.0 .or. f0.ge.(5000.0-375.0) ) cycle call ft2_downsample(iwave,f0,c2) ! downsample from 160s/Symbol to 10s/Symbol ! 750 samples/second here @@ -93,8 +93,6 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) cterm=cterm*cc0 endif enddo -! write(60,3001) if,is,abs(csync1) -!3001 format(2i6,f10.3) if(abs(csync1).gt.sybest) then ibest=is sybest=abs(csync1) @@ -103,8 +101,6 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) enddo enddo -!dfbest=0.0 -!ibest=187 a=0. a(1)=-dfbest call twkfreq1(c2,NMAX/16,fs,a,cb) @@ -189,18 +185,37 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) do i=1,ndecodes if(decodes(i).eq.message) idupe=1 enddo - if(idupe.eq.1) goto 888 + if(idupe.eq.1) exit ndecodes=ndecodes+1 decodes(ndecodes)=message + xsnr=db(sybest*sybest) - 115.0 !### Rough estimate of S/N ### nsnr=nint(xsnr) freq=f0+dfbest - write(*,1212) cdatetime,nsnr,ibest/750.0,nint(freq),message, & + write(*,1000) cdatetime,nsnr,ibest/750.0,nint(freq),message, & nseq,nharderror,nhardmin -1212 format(a17,i4,f6.2,i6,2x,a37,3i5) - goto 888 + write(12,1000) cdatetime,nsnr,ibest/750.0,nint(freq),message, & + nseq,nharderror,nhardmin +1000 format(a17,' Rx',i4,f6.2,i6,3x,a37,3i5) + +!### Temporary: assume most recent decoded message conveys "hiscall". + i0=index(message,' ') + if(i0.ge.3 .and. i0.le.7) then + hiscall=message(i0+1:i0+6) + i1=index(hiscall,' ') + if(i1.gt.0) hiscall=hiscall(1:i1) + endif + nrx=-1 + if(index(message,'CQ ').eq.1) nrx=1 + if((index(message,trim(mycall)//' ').eq.1) .and. & + (index(message,' '//trim(hiscall)//' ').ge.4)) then + if(index(message,' 559 ').gt.8) nrx=2 + if(index(message,' R 559 ').gt.8) nrx=3 + if(index(message,' RR73 ').gt.8) nrx=4 + endif +!### + exit endif enddo ! nseq -888 continue enddo !candidate list return diff --git a/lib/ft2/ft2audio.c b/lib/ft2/ft2audio.c index 3826f4579..b5f19fa40 100644 --- a/lib/ft2/ft2audio.c +++ b/lib/ft2/ft2audio.c @@ -59,7 +59,7 @@ SoundIn( void *inputBuffer, void *outputBuffer, } if(ia >= data->nring) ia=0; //Wrap buffer pointer if necessary - *data->iwrite = ia; //Save buffer pointer + *data->iwrite = ia; //Save buffer pointer iaa=ia; total_time += (double)framesPerBuffer/12000.0; // printf("iwrite: %d\n",*data->iwrite); @@ -165,7 +165,8 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, return(-1); } - // printf("Opening device %d for input, %d for output...\n",ndevice_in,ndevice_out); + // printf("Opening device %d for input, %d for output...\n", + // ndevice_in,ndevice_out); inputParameters.device = ndevice_in; inputParameters.channelCount = 2; @@ -173,7 +174,8 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, inputParameters.suggestedLatency = 0.2; inputParameters.hostApiSpecificStreamInfo = NULL; -// Test if this configuration actually works, so we do not run into an ugly assertion +// Test if this configuration actually works, so we do not run into an +// ugly assertion err_open_in = Pa_IsFormatSupported(&inputParameters, NULL, dSampleRate); if (err_open_in == 0) { @@ -189,16 +191,16 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, if(err_open_in) { // We should have no error here usually printf("Error opening input audio stream:\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), + err_open_in); err = 1; } else { // printf("Successfully opened audio input.\n"); } } else { printf("Error opening input audio stream.\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), + err_open_in); err = 1; } @@ -208,7 +210,8 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, outputParameters.suggestedLatency = 0.2; outputParameters.hostApiSpecificStreamInfo = NULL; -// Test if this configuration actually works, so we do not run into an ugly assertion +// Test if this configuration actually works, so we do not run into an +// ugly assertion. err_open_out = Pa_IsFormatSupported(NULL, &outputParameters, dSampleRate); if (err_open_out == 0) { @@ -224,36 +227,34 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, if(err_open_out) { // We should have no error here usually printf("Error opening output audio stream!\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), + err_open_out); err += 2; } else { // printf("Successfully opened audio output.\n"); } } else { printf("Error opening output audio stream.\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), + err_open_out); err += 2; } // if there was no error in opening both streams start them if (err == 0) { err_start_in = Pa_StartStream(instream); //Start input stream - if(err_start_in) { printf("Error starting input audio stream!\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_in), err_start_in); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_in), + err_start_in); err += 4; } - err_start_out = Pa_StartStream(outstream); //Start output stream - + err_start_out = Pa_StartStream(outstream); //Start output stream if(err_start_out) { printf("Error starting output audio stream!\n"); - printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_out), err_start_out); - + printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_out), + err_start_out); err += 8; } } @@ -322,7 +323,8 @@ int padevsub_(int *idevin, int *idevout) // if(i == Pa_GetDefaultOutputDevice()) ndefout = i; nchin[i]=pdi->maxInputChannels; nchout[i]=pdi->maxOutputChannels; - printf(" %2d %2d %2d %s\n",i,nchin[i],nchout[i],pdi->name); + printf(" %2d %2d %2d %s\n",i,nchin[i],nchout[i], + pdi->name); } printf("\nUser requested devices: Input = %2d Output = %2d\n", diff --git a/lib/ft2/gcom1.f90 b/lib/ft2/gcom1.f90 index d4a952e5c..48bf391c6 100644 --- a/lib/ft2/gcom1.f90 +++ b/lib/ft2/gcom1.f90 @@ -15,6 +15,10 @@ integer nTransmitting !Actually transmitting? integer nTxOK !OK to transmit? integer nport !COM port for PTT logical tx_once !Transmit one message, then exit +logical ltx !True if msg i has been transmitted +logical lrx !True if msg i has been received +logical autoseq +logical QSO_in_progress integer*2 y1 !Ring buffer for audio channel 0 integer*2 y2 !Ring buffer for audio channel 1 integer*2 iwave !Data for Tx audio @@ -26,5 +30,5 @@ character*3 exch character*37 txmsg common/gcom1/snrdb,ndevin,ndevout,iwrite,itx,ngo,nTransmitting,nTxOK,nport, & - tx_once, y1(NRING),y2(NRING),iwave(NTZ),mycall,hiscall, & - hiscall_next,mygrid,exch,txmsg + ntxed,tx_once, y1(NRING),y2(NRING),iwave(NTZ),ltx(5),lrx(5),autoseq, & + QSO_in_progress,mycall,hiscall,hiscall_next,mygrid,exch,txmsg