Many improvements to ft2, including:

- SNR displayed on decode line
 - Separate transmit() subroutine
 - Output sent to all_ft2.txt
 - Display Rx level (hit L to toggle On/Off)
 - Auto-sequencing  (hit A to toggle On/Off)
This commit is contained in:
Joe Taylor 2019-01-16 13:10:36 -05:00
parent 60fb12dcd4
commit f194621695
4 changed files with 172 additions and 86 deletions

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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