Progress: ft2.exe is now basically functional in audio-loopback tests.

This commit is contained in:
Joe Taylor 2019-01-15 15:05:04 -05:00
parent 8a6cee7e26
commit bbbe83ffe5
7 changed files with 93 additions and 78 deletions

View File

@ -6,7 +6,7 @@ program ft2
logical allok logical allok
character*20 pttport character*20 pttport
character*8 arg character*8 arg
integer*2 iwave2(30000) ! integer*2 iwave2(30000)
allok=.true. allok=.true.
! Get home-station details ! Get home-station details
@ -38,7 +38,7 @@ program ft2
nwave=NTZ nwave=NTZ
nfsample=12000 nfsample=12000
ngo=1 ngo=1
npabuf=1280 npabuf=1152
ntxok=0 ntxok=0
ntransmitting=0 ntransmitting=0
tx_once=.false. tx_once=.false.
@ -52,25 +52,16 @@ program ft2
read(arg,*) f0 read(arg,*) f0
call getarg(3,arg) call getarg(3,arg)
read(arg,*) snrdb read(arg,*) snrdb
nTxOK=1
tx_once=.true. tx_once=.true.
call ft2_iwave(txmsg,f0,snrdb,iwave) call ft2_iwave(txmsg,f0,snrdb,iwave)
nTxOK=1
endif endif
iwave2(1:23040)=iwave ! Start the audio streams
iwave2(23041:30000)=0
nutc=0
nfqso=nint(f0)
call ft2_decode(nutc,nfqso,iwave2)
ierr=ft2audio(idevin,idevout,npabuf,nright,y1,y2,NRING,iwrite,itx, & ierr=ft2audio(idevin,idevout,npabuf,nright,y1,y2,NRING,iwrite,itx, &
iwave,nwave,nfsample,nTxOK,nTransmitting,ngo) iwave,nwave,nfsample,nTxOK,nTransmitting,ngo)
if(ierr.ne.0) then if(ierr.ne.0) then
print*,'Error',ierr,' in JTaudio, you will only be able to work offline.' print*,'Error',ierr,' starting audio input and/or output.'
else
write(*,1006)
1006 format('Audio streams terminated normally.')
endif endif
999 end program ft2 999 end program ft2
@ -78,33 +69,31 @@ program ft2
subroutine update(total_time,ic1,ic2) subroutine update(total_time,ic1,ic2)
real*8 total_time real*8 total_time
integer*8 count00,count0,count1,clkfreq
integer ptt integer ptt
integer*2 id(30000)
logical transmitted logical transmitted
integer*2 id(30000),id2(30000) character*30 line
character cdate*8,ctime*10,cdatetime*17
include 'gcom1.f90' include 'gcom1.f90'
data nt0/-1/,transmitted/.false./,snr/0.0/ data nt0/-1/,transmitted/.false./,snr/-99.0/,count00/-1/
save nt0,transmitted,snr save nt0,transmitted,snr,count00
if(ic1.ne.0 .or. ic2.ne.0) then 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 if(nTxOK.eq.0 .and. ntransmitting.eq.0) then
nd=0 nd=0
if(ic1.eq.0 .and. ic2.eq.59) nd=7 !F1 if(ic1.eq.0 .and. ic2.eq.59) nd=1 !F1
if(ic1.eq.0 .and. ic2.eq.60) nd=6 !F2 if(ic1.eq.0 .and. ic2.eq.60) nd=2 !F2
if(ic1.eq.0 .and. ic2.eq.61) nd=5 !F3 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.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 if(nd.gt.0) then
i1=ptt(nport,1,1,iptt) i1=ptt(nport,1,1,iptt)
ntxok=1 ntxok=1
n=1000 if(nd.eq.1) txmsg='CQ K1JT FN20'
nwave=NTZ if(nd.eq.2) txmsg='K9AN K1JT 559 NJ'
do i=1,nwave/nd call ft2_iwave(txmsg,1500.0,99.0,iwave)
ib=i*nd
ia=ib-nd+1
iwave(ia:ib)=n
n=-n
enddo
endif endif
endif endif
if(ic1.eq.13 .and. ic2.eq.0) hiscall=hiscall_next if(ic1.eq.13 .and. ic2.eq.0) hiscall=hiscall_next
@ -138,13 +127,25 @@ subroutine update(total_time,ic1,ic2)
enddo enddo
nutc=0 nutc=0
nfqso=1500 nfqso=1500
call ft2_iwave(txmsg,1500.0,snr,id2) !### ndecodes=0
snr=snr-1.0 if(maxval(abs(id)).gt.0) then
call ft2_decode(nutc,nfqso,id2) !### call date_and_time(cdate,ctime)
!### call ft2_decode(nutc,nfqso,id) cdatetime=cdate(3:8)//'_'//ctime
call system_clock(count0,clkfreq)
write(*,1010) nt,total_time,iwrite,itx,ntxok,ntransmitting,sigdb,snr call ft2_decode(cdatetime,nfqso,id,ndecodes)
1010 format(i6,f9.3,4i6,f6.1,f6.0) 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 nt0=nt
max1=0 max1=0
max2=0 max2=0

View File

@ -1,4 +1,4 @@
subroutine ft2_decode(nutc,nfqso,iwave) subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes)
use crc use crc
use packjt77 use packjt77
@ -6,6 +6,7 @@ subroutine ft2_decode(nutc,nfqso,iwave)
character message*37,c77*77 character message*37,c77*77
character*37 decodes(100) character*37 decodes(100)
character*120 data_dir character*120 data_dir
character*17 cdatetime
complex c2(0:NMAX/16-1) !Complex waveform complex c2(0:NMAX/16-1) !Complex waveform
complex cb(0:NMAX/16-1) complex cb(0:NMAX/16-1)
complex cd(0:144*10-1) !Complex waveform complex cd(0:144*10-1) !Complex waveform
@ -65,7 +66,6 @@ subroutine ft2_decode(nutc,nfqso,iwave)
ndecodes=0 ndecodes=0
do icand=1,ncand do icand=1,ncand
f0=candidate(1,icand) f0=candidate(1,icand)
! print*,'A',ncand,f0
xsnr=1.0 xsnr=1.0
if( f0.le.375.0 .or. f0.ge.(5000.0-375.0) ) cycle 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 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 decodes(ndecodes)=message
nsnr=nint(xsnr) nsnr=nint(xsnr)
freq=f0+dfbest 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 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 goto 888
endif endif
enddo ! nseq enddo ! nseq
888 continue 888 continue
enddo !candidate list enddo !candidate list
return
end subroutine ft2_decode end subroutine ft2_decode
subroutine getbitmetric(ib,ps,ns,xmet) subroutine getbitmetric(ib,ps,ns,xmet)

View File

@ -6,9 +6,9 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave)
include 'ft2_params.f90' !Set various constants include 'ft2_params.f90' !Set various constants
parameter (NWAVE=NN*NSPS) parameter (NWAVE=NN*NSPS)
character msg37*37,msgsent37*37 character msg37*37,msgsent37*37
real wave(NMAX) real wave(NWAVE),xnoise(NWAVE)
integer itone(NN) 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) twopi=8.0*atan(1.0)
fs=12000.0 !Sample rate (Hz) fs=12000.0 !Sample rate (Hz)
@ -19,8 +19,8 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave)
bw=1.5*baud !Occupied bandwidth (Hz) bw=1.5*baud !Occupied bandwidth (Hz)
txt=NZ*dt !Transmission length (s) txt=NZ*dt !Transmission length (s)
bandwidth_ratio=2500.0/(fs/2.0) bandwidth_ratio=2500.0/(fs/2.0)
sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) ! sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb)
if(snrdb.gt.90.0) sig=1.0 ! if(snrdb.gt.90.0) sig=1.0
txt=NN*NSPS/12000.0 txt=NN*NSPS/12000.0
! Source-encode, then get itone(): ! Source-encode, then get itone():
@ -29,38 +29,36 @@ subroutine ft2_iwave(msg37,f0,snrdb,iwave)
k=0 k=0
phi=0.0 phi=0.0
sqsig=0.
do j=1,NN !Generate real waveform do j=1,NN !Generate real waveform
dphi=twopi*(f0*dt+(hmod/2.0)*(2*itone(j)-1)/real(NSPS)) dphi=twopi*(f0*dt+(hmod/2.0)*(2*itone(j)-1)/real(NSPS))
do i=1,NSPS do i=1,NSPS
k=k+1 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) phi=mod(phi+dphi,twopi)
enddo enddo
enddo enddo
kz=k
peak=maxval(abs(wave(1:kz))) if(snrdb.gt.90.0) then
! nslots=1 iwave=nint((32767.0/sqrt(2.0))*wave)
! if(width.gt.0.0) call filt8(f0,nslots,width,wave) return
endif
sqnoise=1.e-30
if(snrdb.lt.90) then if(snrdb.lt.90) then
do i=1,NMAX !Add gaussian noise at specified SNR do i=1,NWAVE !Add gaussian noise at specified SNR
xnoise=gran() xnoise(i)=gran() !Noise has rms = 1.0
wave(i)=wave(i) + xnoise
enddo enddo
endif endif
xnoise=xnoise*sqrt(0.5*fs/2500.0)
gain=1.0 fac=30.0
if(snrdb.lt.90.0) then snr_amplitude=10.0**(0.05*snrdb)
wave=gain*wave wave=fac*(snr_amplitude*wave + xnoise)
else
datpk=maxval(abs(wave)) datpk=maxval(abs(wave))
fac=32767.0/datpk print*,'A',snr_amplitude,datpk
wave=fac*wave
endif
if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." iwave=nint((30000.0/datpk)*wave)
iwave(1:kz)=nint(wave(1:kz))
return return
end subroutine ft2_iwave end subroutine ft2_iwave

View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include "portaudio.h" #include "portaudio.h"
#include <string.h> #include <string.h>
#include <time.h>
int iaa; int iaa;
int icc; int icc;
@ -15,7 +16,7 @@ typedef struct
int *Transmitting; int *Transmitting;
int *nwave; int *nwave;
int *nright; int *nright;
int nbuflen; int nring;
int nfs; int nfs;
short *y1; short *y1;
short *y2; 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 *data->iwrite = ia; //Save buffer pointer
iaa=ia; iaa=ia;
total_time += (double)framesPerBuffer/12000.0; total_time += (double)framesPerBuffer/12000.0;
// printf("iwrite: %d\n",*data->iwrite);
return 0; return 0;
} }
@ -78,28 +80,41 @@ SoundOut( void *inputBuffer, void *outputBuffer,
static short int n2; static short int n2;
static int ic=0; static int ic=0;
static int TxOKz=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); // printf("txOK: %d %d\n",TxOKz,*data->TxOK);
if(*data->TxOK && (!TxOKz)) ic=0; if(*data->TxOK && (!TxOKz)) ic=0; //Reset buffer pointer to start Tx
TxOKz=*data->TxOK; *data->Transmitting=*data->TxOK; //Set the "transmitting" flag
*data->Transmitting=*data->TxOK;
if(*data->TxOK) { 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++ ) { for(i=0 ; i < framesPerBuffer; i++ ) {
n2=data->iwave[ic]; n2=data->iwave[ic];
*wptr++ = n2; //left *wptr++ = n2; //left
*wptr++ = n2; //right *wptr++ = n2; //right
ic++; ic++;
if(ic >= *data->nwave) { if(ic > *data->nwave) {
*data->TxOK = 0; *data->TxOK = 0;
*data->Transmitting = 0; *data->Transmitting = 0;
*data->iwrite = 0; //Reset Rx buffer pointer to 0 *data->iwrite = 0; //Reset Rx buffer pointer to 0
ic=0; ic=0;
tend=clock();
double TxT=((double)(tend-tstart))/CLOCKS_PER_SEC;
// printf("End Tx, TxT = %f nSent = %d\n",TxT,nsent);
break; break;
} }
} }
nsent += framesPerBuffer;
} else { } else {
memset((void*)outputBuffer, 0, 2*sizeof(short)*framesPerBuffer); 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, 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 *itx, short iwave[], int *nwave, int *nfsample,
int *TxOK, int *Transmitting, int *ngo) int *TxOK, int *Transmitting, int *ngo)
@ -134,7 +149,7 @@ int ft2audio_(int *ndevin, int *ndevout, int *npabuf, int *nright,
data.Transmitting = Transmitting; data.Transmitting = Transmitting;
data.y1 = y1; data.y1 = y1;
data.y2 = y2; data.y2 = y2;
data.nbuflen = *nbuflen; data.nring = *nring;
data.nright = nright; data.nright = nright;
data.nwave = nwave; data.nwave = nwave;
data.iwave = iwave; data.iwave = iwave;

View File

@ -2,5 +2,5 @@ gcc -c ft2audio.c
gcc -c ptt.c gcc -c ptt.c
gfortran -c ../77bit/packjt77.f90 gfortran -c ../77bit/packjt77.f90
gfortran -c ../crc.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 rm *.o *.mod

View File

@ -2,7 +2,7 @@
!--------------------------------------------------------------------------- !---------------------------------------------------------------------------
integer NRING !Length of Rx ring buffer integer NRING !Length of Rx ring buffer
integer NTZ !Length of Tx waveform in samples 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(NTZ=23040) !144*160
parameter(NMAX=30000) !2.5*12000 parameter(NMAX=30000) !2.5*12000
real snrdb real snrdb

View File

@ -43,7 +43,7 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand)
indx=0 indx=0
call indexx(savsm(nfa:nfb),np,indx) call indexx(savsm(nfa:nfb),np,indx)
xn=savsm(nfa+indx(nint(0.3*np))) xn=savsm(nfa+indx(nint(0.3*np)))
savsm=savsm/xn if(xn.ne.0) savsm=savsm/xn
imax=-1 imax=-1
xmax=-99. xmax=-99.
do i=2,NH1-1 do i=2,NH1-1
@ -60,5 +60,5 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand)
candidate(1,ncand)=f0 candidate(1,ncand)=f0
endif endif
return return
end subroutine getcandidates2 end subroutine getcandidates2