FT4: Change Fortran code to NSPS=576 and make necessary accompanying

changes on the C++ side. Basically works except that Tx audio has
incorrect DT and audio is truncated at the end. Also, command line
decoding using JT9 is not as sensitive as decoding from within WSJT-X.
This commit is contained in:
Steve Franke 2019-05-22 17:02:15 -05:00
parent 80307b64ad
commit a9623703b3
10 changed files with 31 additions and 32 deletions

View File

@ -91,8 +91,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
if (synchronize && !m_tuning && !m_bFastMode) { if (synchronize && !m_tuning && !m_bFastMode) {
m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000)); m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000));
} }
if(symbolsLength==105 and framesPerSymbol==512 if(symbolsLength==105 and framesPerSymbol==576
and (toneSpacing==12000.0/512.0 or toneSpacing==-2.0)) { and (toneSpacing==12000.0/576.0 or toneSpacing==-2.0)) {
//### FT4 parameters //### FT4 parameters
m_ic=0; m_ic=0;
m_silentFrames=0; m_silentFrames=0;

View File

@ -4,7 +4,7 @@ subroutine ft4_downsample(dd,newdata,f0,c)
! Output: Complex data in c(), sampled at 1200 Hz ! Output: Complex data in c(), sampled at 1200 Hz
include 'ft4_params.f90' include 'ft4_params.f90'
parameter (NFFT2=NMAX/16) parameter (NFFT2=NMAX/NDOWN)
real dd(NMAX) real dd(NMAX)
complex c(0:NMAX/NDOWN-1) complex c(0:NMAX/NDOWN-1)
complex c1(0:NFFT2-1) complex c1(0:NFFT2-1)

View File

@ -6,11 +6,11 @@ parameter (ND=87) !Data symbols
parameter (NS=16) !Sync symbols parameter (NS=16) !Sync symbols
parameter (NN=NS+ND) !Sync and data symbols (103) parameter (NN=NS+ND) !Sync and data symbols (103)
parameter (NN2=NS+ND+2) !Total channel symbols (105) parameter (NN2=NS+ND+2) !Total channel symbols (105)
parameter (NSPS=512) !Samples per symbol at 12000 S/s parameter (NSPS=576) !Samples per symbol at 12000 S/s
parameter (NZ=NSPS*NN) !Sync and Data samples (52736) parameter (NZ=NSPS*NN) !Sync and Data samples (59328)
parameter (NZ2=NSPS*NN2) !Total samples in shaped waveform (53760) parameter (NZ2=NSPS*NN2) !Total samples in shaped waveform (60480)
parameter (NMAX=18*3456) !Samples in iwave parameter (NMAX=21*3456) !Samples in iwave (72576)
parameter (NFFT1=2048, NH1=NFFT1/2) !Length of FFTs for symbol spectra parameter (NFFT1=2304, NH1=NFFT1/2) !Length of FFTs for symbol spectra
parameter (NSTEP=NSPS) !Coarse time-sync step size parameter (NSTEP=NSPS) !Coarse time-sync step size
parameter (NHSYM=(NMAX-NFFT1)/NSTEP) !Number of symbol spectra (1/4-sym steps) parameter (NHSYM=(NMAX-NFFT1)/NSTEP) !Number of symbol spectra (1/4-sym steps)
parameter (NDOWN=16) !Downsample factor parameter (NDOWN=18) !Downsample factor

View File

@ -6,7 +6,7 @@ program ft4sim
use packjt77 use packjt77
include 'ft4_params.f90' !Set various constants include 'ft4_params.f90' !Set various constants
parameter (NWAVE=NN*NSPS) parameter (NWAVE=NN*NSPS)
parameter (NZZ=18*3456) !62208 parameter (NZZ=21*3456) !72576
type(hdr) h !Header for .wav file type(hdr) h !Header for .wav file
character arg*12,fname*17 character arg*12,fname*17
character msg37*37,msgsent37*37 character msg37*37,msgsent37*37
@ -51,12 +51,11 @@ program ft4sim
hmod=1.0 !Modulation index (0.5 is MSK, 1.0 is FSK) hmod=1.0 !Modulation index (0.5 is MSK, 1.0 is FSK)
tt=NSPS*dt !Duration of symbols (s) tt=NSPS*dt !Duration of symbols (s)
baud=1.0/tt !Keying rate (baud) baud=1.0/tt !Keying rate (baud)
txt=NZ*dt !Transmission length (s) txt=NZ2*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
! Source-encode, then get itone() ! Source-encode, then get itone()
i3=-1 i3=-1

View File

@ -2,8 +2,8 @@ subroutine gen_ft4wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave)
real wave(nwave) real wave(nwave)
complex cwave(nwave) complex cwave(nwave)
real pulse(6144) !512*4*3 real pulse(6912) !576*4*3
real dphi(0:240000-1) real dphi(0:250000-1)
integer itone(nsym) integer itone(nsym)
logical first logical first
data first/.true./ data first/.true./

View File

@ -61,7 +61,7 @@ subroutine getcandidates4(dd,fa,fb,syncmin,nfqso,maxcand,savg,candidate, &
! call ft4_baseline(savg,nfa,nfb,sbase) ! call ft4_baseline(savg,nfa,nfb,sbase)
! savsm=savsm/sbase ! savsm=savsm/sbase
f_offset = -1.5*12000/512 f_offset = -1.5*12000.0/NSPS
do i=nfa+1,nfb-1 do i=nfa+1,nfb-1
if(savsm(i).ge.savsm(i-1) .and. savsm(i).ge.savsm(i+1) .and. & if(savsm(i).ge.savsm(i-1) .and. savsm(i).ge.savsm(i+1) .and. &
savsm(i).ge.syncmin) then savsm(i).ge.syncmin) then

View File

@ -9,8 +9,8 @@ subroutine subtractft4(dd,itone,f0,dt)
use timer_module, only: timer use timer_module, only: timer
parameter (NMAX=18*3456,NFRAME=(103+2)*512) parameter (NMAX=21*3456,NSPS=576,NFFT=NMAX,NFILT=1400)
parameter (NFFT=NMAX,NFILT=1400) parameter (NFRAME=(103+2)*NSPS)
real*4 dd(NMAX), window(-NFILT/2:NFILT/2), xjunk real*4 dd(NMAX), window(-NFILT/2:NFILT/2), xjunk
complex cref,camp,cfilt,cw complex cref,camp,cfilt,cw
integer itone(103) integer itone(103)
@ -19,13 +19,13 @@ subroutine subtractft4(dd,itone,f0,dt)
common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX),xjunk(NFRAME) common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX),xjunk(NFRAME)
save first save first
nstart=dt*12000+1-512 nstart=dt*12000+1-NSPS
nsym=103 nsym=103
nsps=512
fs=12000.0 fs=12000.0
icmplx=1 icmplx=1
bt=1.0 bt=1.0
call gen_ft4wave(itone,nsym,nsps,fs,f0,cref,xjunk,icmplx,NFRAME) nss=NSPS
call gen_ft4wave(itone,nsym,nss,fs,f0,cref,xjunk,icmplx,NFRAME)
camp=0. camp=0.
do i=1,nframe do i=1,nframe
id=nstart-1+i id=nstart-1+i

View File

@ -249,14 +249,14 @@ contains
if(dobigfft) dobigfft=.false. if(dobigfft) dobigfft=.false.
sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN)) sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN))
if(sum2.gt.0.0) cd2=cd2/sqrt(sum2) if(sum2.gt.0.0) cd2=cd2/sqrt(sum2)
! Sample rate is now 12000/16 = 750 samples/second ! Sample rate is now 12000/18 = 666.67 samples/second
do isync=1,2 do isync=1,2
if(isync.eq.1) then if(isync.eq.1) then
idfmin=-12 idfmin=-12
idfmax=12 idfmax=12
idfstp=3 idfstp=3
ibmin=-200 ibmin=-333
ibmax=950 ibmax=1000
ibstp=4 ibstp=4
else else
idfmin=idfbest-4 idfmin=idfbest-4
@ -493,7 +493,7 @@ contains
call unpack77(c77,1,message,unpk77_success) call unpack77(c77,1,message,unpk77_success)
if(unpk77_success.and.dosubtract) then if(unpk77_success.and.dosubtract) then
call get_ft4_tones_from_77bits(message77,i4tone) call get_ft4_tones_from_77bits(message77,i4tone)
dt=real(ibest)/750.0 dt=real(ibest)/666.67
call timer('subtract',0) call timer('subtract',0)
call subtractft4(dd,i4tone,f0,dt) call subtractft4(dd,i4tone,f0,dt)
call timer('subtract',1) call timer('subtract',1)
@ -506,12 +506,12 @@ contains
ndecodes=ndecodes+1 ndecodes=ndecodes+1
decodes(ndecodes)=message decodes(ndecodes)=message
if(snr.gt.0.0) then if(snr.gt.0.0) then
xsnr=10*log10(snr)-14.0 xsnr=10*log10(snr)-14.8
else else
xsnr=-20.0 xsnr=-20.0
endif endif
nsnr=nint(max(-20.0,xsnr)) nsnr=nint(max(-20.0,xsnr))
xdt=ibest/750.0 - 0.5 xdt=ibest/666.67 - 0.5
!write(21,'(i6.6,i5,2x,f4.1,i6,2x,a37,2x,f4.1,3i3)') nutc,nsnr,xdt,nint(f0),message,sync,iaptype,ipass,isp !write(21,'(i6.6,i5,2x,f4.1,i6,2x,a37,2x,f4.1,3i3)') nutc,nsnr,xdt,nint(f0),message,sync,iaptype,ipass,isp
call this%callback(sync,nsnr,xdt,f0,message,iaptype,qual) call this%callback(sync,nsnr,xdt,f0,message,iaptype,qual)
exit exit

View File

@ -1466,7 +1466,7 @@ void MainWindow::dataSink(qint64 frames)
} }
m_fileToSave.clear (); m_fileToSave.clear ();
int samples=m_TRperiod*12000; int samples=m_TRperiod*12000;
if(m_mode=="FT4") samples=18*3456; if(m_mode=="FT4") samples=21*3456;
// the following is potential a threading hazard - not a good // the following is potential a threading hazard - not a good
// idea to pass pointer to be processed in another thread // idea to pass pointer to be processed in another thread
@ -3428,7 +3428,7 @@ void MainWindow::guiUpdate()
if(m_TRperiod==0) m_TRperiod=60.0; if(m_TRperiod==0) m_TRperiod=60.0;
txDuration=0.0; txDuration=0.0;
if(m_modeTx=="FT4") txDuration=0.35 + 105*512/12000.0; // FT4 if(m_modeTx=="FT4") txDuration=1.0 + 105*576/12000.0; // FT4
if(m_modeTx=="FT8") txDuration=1.0 + 79*1920/12000.0; // FT8 if(m_modeTx=="FT8") txDuration=1.0 + 79*1920/12000.0; // FT8
if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4 if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4
if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9 if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9
@ -3748,7 +3748,7 @@ void MainWindow::guiUpdate()
genft4_(message, &ichk, msgsent, const_cast<char *> (ft4msgbits), genft4_(message, &ichk, msgsent, const_cast<char *> (ft4msgbits),
const_cast<int *>(itone), 37, 37); const_cast<int *>(itone), 37, 37);
int nsym=103; int nsym=103;
int nsps=4*512; int nsps=4*576;
float fsample=48000.0; float fsample=48000.0;
float f0=ui->TxFreqSpinBox->value() - m_XIT; float f0=ui->TxFreqSpinBox->value() - m_XIT;
int nwave=(nsym+2)*nsps; int nwave=(nsym+2)*nsps;
@ -5652,7 +5652,7 @@ void MainWindow::on_actionFT4_triggered()
Q_EMIT FFTSize (m_FFTSize); Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=18; m_hsymStop=18;
setup_status_bar (bVHF); setup_status_bar (bVHF);
m_toneSpacing=12000.0/512.0; m_toneSpacing=12000.0/576.0;
ui->actionFT4->setChecked(true); ui->actionFT4->setChecked(true);
m_wideGraph->setMode(m_mode); m_wideGraph->setMode(m_mode);
m_wideGraph->setModeTx(m_modeTx); m_wideGraph->setModeTx(m_modeTx);
@ -6949,7 +6949,7 @@ void MainWindow::transmit (double snr)
m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); m_dateTimeSentTx3=QDateTime::currentDateTimeUtc();
toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform.
Q_EMIT sendMessage (NUM_FT4_SYMBOLS, Q_EMIT sendMessage (NUM_FT4_SYMBOLS,
512.0, ui->TxFreqSpinBox->value() - m_XIT, 576.0, ui->TxFreqSpinBox->value() - m_XIT,
toneSpacing, m_soundOutput, m_config.audio_output_channel(), toneSpacing, m_soundOutput, m_config.audio_output_channel(),
true, false, snr, m_TRperiod); true, false, snr, m_TRperiod);
} }

View File

@ -411,7 +411,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
} }
float bw=9.0*12000.0/m_nsps; //JT9 float bw=9.0*12000.0/m_nsps; //JT9
if(m_mode=="FT4") bw=3*12000.0/512.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ###
if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8
if(m_mode=="JT4") { //JT4 if(m_mode=="JT4") { //JT4