From bbbe83ffe500617e1ae2aee480f29c9393ae4db8 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 15 Jan 2019 15:05:04 -0500 Subject: [PATCH] Progress: ft2.exe is now basically functional in audio-loopback tests. --- lib/ft2/ft2.f90 | 73 +++++++++++++++++++------------------- lib/ft2/ft2_decode.f90 | 11 +++--- lib/ft2/ft2_iwave.f90 | 46 ++++++++++++------------ lib/ft2/ft2audio.c | 31 +++++++++++----- lib/ft2/g4.cmd | 2 +- lib/ft2/gcom1.f90 | 2 +- lib/ft2/getcandidates2.f90 | 6 ++-- 7 files changed, 93 insertions(+), 78 deletions(-) diff --git a/lib/ft2/ft2.f90 b/lib/ft2/ft2.f90 index 204a8a78f..21e5d154d 100644 --- a/lib/ft2/ft2.f90 +++ b/lib/ft2/ft2.f90 @@ -6,7 +6,7 @@ program ft2 logical allok character*20 pttport character*8 arg - integer*2 iwave2(30000) +! integer*2 iwave2(30000) allok=.true. ! Get home-station details @@ -38,7 +38,7 @@ program ft2 nwave=NTZ nfsample=12000 ngo=1 - npabuf=1280 + npabuf=1152 ntxok=0 ntransmitting=0 tx_once=.false. @@ -52,25 +52,16 @@ program ft2 read(arg,*) f0 call getarg(3,arg) read(arg,*) snrdb - nTxOK=1 tx_once=.true. call ft2_iwave(txmsg,f0,snrdb,iwave) + nTxOK=1 endif - - iwave2(1:23040)=iwave - iwave2(23041:30000)=0 - nutc=0 - nfqso=nint(f0) - call ft2_decode(nutc,nfqso,iwave2) - +! Start the audio streams ierr=ft2audio(idevin,idevout,npabuf,nright,y1,y2,NRING,iwrite,itx, & iwave,nwave,nfsample,nTxOK,nTransmitting,ngo) if(ierr.ne.0) then - print*,'Error',ierr,' in JTaudio, you will only be able to work offline.' - else - write(*,1006) -1006 format('Audio streams terminated normally.') + print*,'Error',ierr,' starting audio input and/or output.' endif 999 end program ft2 @@ -78,33 +69,31 @@ program ft2 subroutine update(total_time,ic1,ic2) real*8 total_time + integer*8 count00,count0,count1,clkfreq integer ptt + integer*2 id(30000) logical transmitted - integer*2 id(30000),id2(30000) + character*30 line + character cdate*8,ctime*10,cdatetime*17 include 'gcom1.f90' - data nt0/-1/,transmitted/.false./,snr/0.0/ - save nt0,transmitted,snr + data nt0/-1/,transmitted/.false./,snr/-99.0/,count00/-1/ + save nt0,transmitted,snr,count00 if(ic1.ne.0 .or. ic2.ne.0) then 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=7 !F1 - if(ic1.eq.0 .and. ic2.eq.60) nd=6 !F2 - if(ic1.eq.0 .and. ic2.eq.61) nd=5 !F3 + 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=3 !F5 + if(ic1.eq.0 .and. ic2.eq.63) nd=5 !F5 if(nd.gt.0) then i1=ptt(nport,1,1,iptt) ntxok=1 - n=1000 - nwave=NTZ - do i=1,nwave/nd - ib=i*nd - ia=ib-nd+1 - iwave(ia:ib)=n - n=-n - enddo + if(nd.eq.1) txmsg='CQ K1JT FN20' + if(nd.eq.2) txmsg='K9AN K1JT 559 NJ' + call ft2_iwave(txmsg,1500.0,99.0,iwave) endif endif if(ic1.eq.13 .and. ic2.eq.0) hiscall=hiscall_next @@ -138,13 +127,25 @@ subroutine update(total_time,ic1,ic2) enddo nutc=0 nfqso=1500 - call ft2_iwave(txmsg,1500.0,snr,id2) !### - snr=snr-1.0 - call ft2_decode(nutc,nfqso,id2) !### -!### call ft2_decode(nutc,nfqso,id) - - write(*,1010) nt,total_time,iwrite,itx,ntxok,ntransmitting,sigdb,snr -1010 format(i6,f9.3,4i6,f6.1,f6.0) + 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) + call system_clock(count1,clkfreq) + tdecode=float(count1-count0)/float(clkfreq) + if(count00.lt.0) count00=count0 + trun=float(count1-count00)/float(clkfreq) + 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 diff --git a/lib/ft2/ft2_decode.f90 b/lib/ft2/ft2_decode.f90 index 5647c8d02..74cab3ee4 100644 --- a/lib/ft2/ft2_decode.f90 +++ b/lib/ft2/ft2_decode.f90 @@ -1,4 +1,4 @@ -subroutine ft2_decode(nutc,nfqso,iwave) +subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes) use crc use packjt77 @@ -6,6 +6,7 @@ subroutine ft2_decode(nutc,nfqso,iwave) character message*37,c77*77 character*37 decodes(100) character*120 data_dir + character*17 cdatetime complex c2(0:NMAX/16-1) !Complex waveform complex cb(0:NMAX/16-1) complex cd(0:144*10-1) !Complex waveform @@ -27,7 +28,7 @@ subroutine ft2_decode(nutc,nfqso,iwave) integer*1 s16(16) logical unpk77_success data s16/0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0/ - + fs=12000.0/NDOWN !Sample rate dt=1/fs !Sample interval after downsample (s) tt=NSPS*dt !Duration of "itone" symbols (s) @@ -65,7 +66,6 @@ subroutine ft2_decode(nutc,nfqso,iwave) ndecodes=0 do icand=1,ncand f0=candidate(1,icand) -! print*,'A',ncand,f0 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 @@ -194,15 +194,16 @@ subroutine ft2_decode(nutc,nfqso,iwave) decodes(ndecodes)=message nsnr=nint(xsnr) freq=f0+dfbest - write(*,1212) nutc,nsnr,ibest/750.0,nint(freq),message, & + write(*,1212) cdatetime,nsnr,ibest/750.0,nint(freq),message, & nseq,nharderror,nhardmin -1212 format(i4.4,i4,f6.2,i6,2x,a37,3i5) +1212 format(a17,i4,f6.2,i6,2x,a37,3i5) goto 888 endif enddo ! nseq 888 continue enddo !candidate list + return end subroutine ft2_decode subroutine getbitmetric(ib,ps,ns,xmet) diff --git a/lib/ft2/ft2_iwave.f90 b/lib/ft2/ft2_iwave.f90 index 94445545d..10b9908de 100644 --- a/lib/ft2/ft2_iwave.f90 +++ b/lib/ft2/ft2_iwave.f90 @@ -6,9 +6,9 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave) include 'ft2_params.f90' !Set various constants parameter (NWAVE=NN*NSPS) character msg37*37,msgsent37*37 - real wave(NMAX) + real wave(NWAVE),xnoise(NWAVE) integer itone(NN) - integer*2 iwave(NMAX) !Generated full-length waveform + integer*2 iwave(NWAVE) !Generated full-length waveform twopi=8.0*atan(1.0) fs=12000.0 !Sample rate (Hz) @@ -19,8 +19,8 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave) bw=1.5*baud !Occupied bandwidth (Hz) txt=NZ*dt !Transmission length (s) bandwidth_ratio=2500.0/(fs/2.0) - sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) - if(snrdb.gt.90.0) sig=1.0 +! sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) +! if(snrdb.gt.90.0) sig=1.0 txt=NN*NSPS/12000.0 ! Source-encode, then get itone(): @@ -29,38 +29,36 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave) k=0 phi=0.0 + sqsig=0. do j=1,NN !Generate real waveform dphi=twopi*(f0*dt+(hmod/2.0)*(2*itone(j)-1)/real(NSPS)) do i=1,NSPS k=k+1 - wave(k)=sig*sin(phi) + wave(k)=sqrt(2.0)*sin(phi) !Signal has rms = 1.0 + sqsig=sqsig + wave(k)**2 phi=mod(phi+dphi,twopi) enddo enddo - kz=k - peak=maxval(abs(wave(1:kz))) -! nslots=1 -! if(width.gt.0.0) call filt8(f0,nslots,width,wave) - + if(snrdb.gt.90.0) then + iwave=nint((32767.0/sqrt(2.0))*wave) + return + endif + + sqnoise=1.e-30 if(snrdb.lt.90) then - do i=1,NMAX !Add gaussian noise at specified SNR - xnoise=gran() - wave(i)=wave(i) + xnoise + do i=1,NWAVE !Add gaussian noise at specified SNR + xnoise(i)=gran() !Noise has rms = 1.0 enddo endif + xnoise=xnoise*sqrt(0.5*fs/2500.0) + fac=30.0 + snr_amplitude=10.0**(0.05*snrdb) + wave=fac*(snr_amplitude*wave + xnoise) + datpk=maxval(abs(wave)) + print*,'A',snr_amplitude,datpk - gain=1.0 - if(snrdb.lt.90.0) then - wave=gain*wave - else - datpk=maxval(abs(wave)) - fac=32767.0/datpk - wave=fac*wave - endif - - if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." - iwave(1:kz)=nint(wave(1:kz)) + iwave=nint((30000.0/datpk)*wave) return end subroutine ft2_iwave diff --git a/lib/ft2/ft2audio.c b/lib/ft2/ft2audio.c index 9d0589d36..3826f4579 100644 --- a/lib/ft2/ft2audio.c +++ b/lib/ft2/ft2audio.c @@ -1,6 +1,7 @@ #include #include "portaudio.h" #include +#include int iaa; int icc; @@ -15,7 +16,7 @@ typedef struct int *Transmitting; int *nwave; int *nright; - int nbuflen; + int nring; int nfs; short *y1; short *y2; @@ -57,10 +58,11 @@ SoundIn( void *inputBuffer, void *outputBuffer, } } - if(ia >= data->nbuflen) ia=0; //Wrap buffer pointer if necessary + if(ia >= data->nring) ia=0; //Wrap buffer pointer if necessary *data->iwrite = ia; //Save buffer pointer iaa=ia; total_time += (double)framesPerBuffer/12000.0; + // printf("iwrite: %d\n",*data->iwrite); return 0; } @@ -78,28 +80,41 @@ SoundOut( void *inputBuffer, void *outputBuffer, static short int n2; static int ic=0; static int TxOKz=0; + static clock_t tstart=-1; + static clock_t tend=-1; + static int nsent=0; // printf("txOK: %d %d\n",TxOKz,*data->TxOK); - if(*data->TxOK && (!TxOKz)) ic=0; - TxOKz=*data->TxOK; - *data->Transmitting=*data->TxOK; + if(*data->TxOK && (!TxOKz)) ic=0; //Reset buffer pointer to start Tx + *data->Transmitting=*data->TxOK; //Set the "transmitting" flag if(*data->TxOK) { + if(!TxOKz) { + // Start of a transmission + tstart=clock(); + nsent=0; + // printf("Start Tx\n"); + } + TxOKz=*data->TxOK; for(i=0 ; i < framesPerBuffer; i++ ) { n2=data->iwave[ic]; *wptr++ = n2; //left *wptr++ = n2; //right ic++; - if(ic >= *data->nwave) { + if(ic > *data->nwave) { *data->TxOK = 0; *data->Transmitting = 0; *data->iwrite = 0; //Reset Rx buffer pointer to 0 ic=0; + tend=clock(); + double TxT=((double)(tend-tstart))/CLOCKS_PER_SEC; + // printf("End Tx, TxT = %f nSent = %d\n",TxT,nsent); break; } } + nsent += framesPerBuffer; } else { memset((void*)outputBuffer, 0, 2*sizeof(short)*framesPerBuffer); } @@ -110,7 +125,7 @@ SoundOut( void *inputBuffer, void *outputBuffer, /*******************************************************************/ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, - short y1[], short y2[], int *nbuflen, int *iwrite, + short y1[], short y2[], int *nring, int *iwrite, int *itx, short iwave[], int *nwave, int *nfsample, int *TxOK, int *Transmitting, int *ngo) @@ -134,7 +149,7 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright, data.Transmitting = Transmitting; data.y1 = y1; data.y2 = y2; - data.nbuflen = *nbuflen; + data.nring = *nring; data.nright = nright; data.nwave = nwave; data.iwave = iwave; diff --git a/lib/ft2/g4.cmd b/lib/ft2/g4.cmd index d6d9134e4..5abf200e6 100644 --- a/lib/ft2/g4.cmd +++ b/lib/ft2/g4.cmd @@ -2,5 +2,5 @@ gcc -c ft2audio.c gcc -c ptt.c gfortran -c ../77bit/packjt77.f90 gfortran -c ../crc.f90 -gfortran -o ft2 -fbounds-check -fno-second-underscore -Wall -Wno-conversion -Wno-character-truncation ft2.f90 ft2_iwave.f90 ft2_decode.f90 getcandidates2.f90 ft2audio.o ptt.o libwsjt_fort.a libwsjt_cxx.a libportaudio.a ../libfftw3f_win.a -lwinmm +gfortran -o ft2 -fbounds-check -fno-second-underscore -ffpe-trap=invalid,zero -Wall -Wno-conversion -Wno-character-truncation ft2.f90 ft2_iwave.f90 ft2_decode.f90 getcandidates2.f90 ft2audio.o ptt.o libwsjt_fort.a libwsjt_cxx.a libportaudio.a ../libfftw3f_win.a -lwinmm rm *.o *.mod diff --git a/lib/ft2/gcom1.f90 b/lib/ft2/gcom1.f90 index fa2262127..d4a952e5c 100644 --- a/lib/ft2/gcom1.f90 +++ b/lib/ft2/gcom1.f90 @@ -2,7 +2,7 @@ !--------------------------------------------------------------------------- integer NRING !Length of Rx ring buffer integer NTZ !Length of Tx waveform in samples -parameter(NRING=32768) !About 2.7 s at 12000 sam/sec +parameter(NRING=230400) !Ring buffer at 12000 samples/sec parameter(NTZ=23040) !144*160 parameter(NMAX=30000) !2.5*12000 real snrdb diff --git a/lib/ft2/getcandidates2.f90 b/lib/ft2/getcandidates2.f90 index d7e75097c..dd5dac507 100644 --- a/lib/ft2/getcandidates2.f90 +++ b/lib/ft2/getcandidates2.f90 @@ -43,7 +43,7 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand) indx=0 call indexx(savsm(nfa:nfb),np,indx) xn=savsm(nfa+indx(nint(0.3*np))) - savsm=savsm/xn + if(xn.ne.0) savsm=savsm/xn imax=-1 xmax=-99. do i=2,NH1-1 @@ -59,6 +59,6 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand) if(ncand.lt.maxcand) ncand=ncand+1 candidate(1,ncand)=f0 endif - -return + + return end subroutine getcandidates2