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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include "portaudio.h"
#include <string.h>
#include <time.h>
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;

View File

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

View File

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

View File

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