Merge branch 'feat-fst280' of bitbucket.org:k1jt/wsjtx into feat-fst280

This commit is contained in:
Steven Franke 2020-07-18 09:02:16 -05:00
commit 510537d4fe
8 changed files with 71 additions and 30 deletions

View File

@ -85,7 +85,7 @@ extern struct {
} echocom_; } echocom_;
extern struct { extern struct {
float wave[14278656]; float wave[(160+2)*134400*4]; /* (nsym+2)*nsps scaled up to 48kHz */
int nslots; int nslots;
int nfreq; int nfreq;
int i3bit[5]; int i3bit[5];

View File

@ -67,9 +67,10 @@ program fst240sim
nz=nsps*NN nz=nsps*NN
txt=nz*dt !Transmission length (s) txt=nz*dt !Transmission length (s)
tt=nsps*dt !Duration of symbols (s) tt=nsps*dt !Duration of symbols (s)
allocate( c0(0:nmax-1) ) nwave=max(nmax,(NN+2)*nsps)
allocate( c(0:nmax-1) ) allocate( c0(0:nwave-1) )
allocate( wave(nmax) ) allocate( c(0:nwave-1) )
allocate( wave(nwave) )
allocate( iwave(nmax) ) allocate( iwave(nmax) )
bandwidth_ratio=2500.0/(fs/2.0) bandwidth_ratio=2500.0/(fs/2.0)
@ -108,7 +109,7 @@ program fst240sim
fsample=12000.0 fsample=12000.0
icmplx=1 icmplx=1
f0=f00+1.5*hmod*baud f0=f00+1.5*hmod*baud
call gen_fst240wave(itone,NN,nsps,nmax,fsample,hmod,f0,icmplx,c0,wave) call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,f0,icmplx,c0,wave)
k=nint((xdt+1.0)/dt) k=nint((xdt+1.0)/dt)
if(nsec.eq.15) k=nint((xdt+0.5)/dt) if(nsec.eq.15) k=nint((xdt+0.5)/dt)
c0=cshift(c0,-k) c0=cshift(c0,-k)
@ -117,7 +118,7 @@ program fst240sim
do ifile=1,nfiles do ifile=1,nfiles
c=c0 c=c0
if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nmax,NZ,fs,delay,fspread) if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c,nwave,NZ,fs,delay,fspread)
c=sig*c c=sig*c
wave=real(c) wave=real(c)
if(snrdb.lt.90) then if(snrdb.lt.90) then
@ -135,7 +136,7 @@ program fst240sim
wave=fac*wave wave=fac*wave
endif endif
if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped." if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped."
iwave=nint(wave) iwave=nint(wave(:size(iwave)))
h=default_header(12000,nmax) h=default_header(12000,nmax)
if(nmax/12000.le.30) then if(nmax/12000.le.30) then
write(fname,1102) ifile write(fname,1102) ifile

View File

@ -68,7 +68,7 @@ contains
logical badsync,unpk77_success,single_decode logical badsync,unpk77_success,single_decode
logical first,nohiscall,lwspr,ex logical first,nohiscall,lwspr,ex
integer*2 iwave(300*12000) integer*2 iwave(30*60*12000)
data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
@ -748,8 +748,8 @@ contains
integer hmod !Modulation index (submode) integer hmod !Modulation index (submode)
integer im(1) !For maxloc integer im(1) !For maxloc
real candidates(100,4) !Candidate list real candidates(100,4) !Candidate list
real s(18000) !Low resolution power spectrum real, allocatable :: s(:) !Low resolution power spectrum
real s2(18000) !CCF of s() with 4 tones real, allocatable :: s2(:) !CCF of s() with 4 tones
real xdb(-3:3) !Model 4-tone CCF peaks real xdb(-3:3) !Model 4-tone CCF peaks
real minsync real minsync
data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/
@ -776,6 +776,8 @@ contains
inb=nint(fh) inb=nint(fh)
endif endif
nnw=nint(48000.*nsps*2./fs)
allocate (s(nnw))
s=0. !Compute low-resloution power spectrum s=0. !Compute low-resloution power spectrum
do i=ina,inb ! noise analysis window includes signal analysis window do i=ina,inb ! noise analysis window includes signal analysis window
j0=nint(i*df2/df1) j0=nint(i*df2/df1)
@ -785,7 +787,8 @@ contains
enddo enddo
ina=max(ina,1+3*hmod) !Don't run off the ends ina=max(ina,1+3*hmod) !Don't run off the ends
inb=min(inb,18000-3*hmod) inb=min(inb,nnw-3*hmod)
allocate (s2(nnw))
s2=0. s2=0.
do i=ina,inb !Compute CCF of s() and 4 tones do i=ina,inb !Compute CCF of s() and 4 tones
s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3)
@ -796,7 +799,7 @@ contains
ncand=0 ncand=0
candidates=0 candidates=0
if(ia.lt.3) ia=3 if(ia.lt.3) ia=3
if(ib.gt.18000-2) ib=18000-2 if(ib.gt.nnw-2) ib=nnw-2
! Find candidates, using the CLEAN algorithm to remove a model of each one ! Find candidates, using the CLEAN algorithm to remove a model of each one
! from s2() after it has been found. ! from s2() after it has been found.
@ -824,6 +827,7 @@ contains
! On "plotspec" special request, compute Doppler spread for a decoded signal ! On "plotspec" special request, compute Doppler spread for a decoded signal
include 'fst240/fst240_params.f90'
complex, allocatable :: cwave(:) !Reconstructed complex signal complex, allocatable :: cwave(:) !Reconstructed complex signal
complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper complex, allocatable :: g(:) !Channel gain, g(t) in QEX paper
real,allocatable :: ss(:) !Computed power spectrum of g(t) real,allocatable :: ss(:) !Computed power spectrum of g(t)
@ -835,15 +839,15 @@ contains
ncall=ncall+1 ncall=ncall+1
nfft=2*nmax nfft=2*nmax
allocate(cwave(0:nmax-1)) nwave=max(nmax,(NN+2)*nsps)
allocate(cwave(0:nwave-1))
allocate(g(0:nfft-1)) allocate(g(0:nfft-1))
wave=0 wave=0
fsample=12000.0 fsample=12000.0
nsym=160 call gen_fst240wave(itone,NN,nsps,nwave,fsample,hmod,fc,1,cwave,wave)
call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc,1,cwave,wave)
cwave=cshift(cwave,-i0*ndown) cwave=cshift(cwave,-i0*ndown)
fac=1.0/32768 fac=1.0/32768
g(0:nmax-1)=fac*float(iwave)*conjg(cwave) g(0:nmax-1)=fac*float(iwave)*conjg(cwave(:nmax-1))
g(nmax:)=0. g(nmax:)=0.
call four2a(g,nfft,1,-1,1) !Forward c2c FFT call four2a(g,nfft,1,-1,1) !Forward c2c FFT
@ -861,7 +865,7 @@ contains
allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz allocate(ss(-ia:ia)) !Allocate space for +/- 10 Hz
sum1=0. sum1=0.
sum2=0. sum2=0.
ns=0 nns=0
do i=-ia,ia do i=-ia,ia
j=i j=i
if(j.lt.0) j=i+nfft if(j.lt.0) j=i+nfft
@ -869,12 +873,12 @@ contains
f=i*df f=i*df
if(f.ge.-4.0 .and. f.le.-2.0) then if(f.ge.-4.0 .and. f.le.-2.0) then
sum1=sum1 + ss(i) !Power between -2 and -4 Hz sum1=sum1 + ss(i) !Power between -2 and -4 Hz
ns=ns+1 nns=nns+1
else if(f.ge.2.0 .and. f.le.4.0) then else if(f.ge.2.0 .and. f.le.4.0) then
sum2=sum2 + ss(i) !Power between +2 and +4 Hz sum2=sum2 + ss(i) !Power between +2 and +4 Hz
endif endif
enddo enddo
avg=min(sum1/ns,sum2/ns) !Compute avg from smaller sum avg=min(sum1/nns,sum2/nns) !Compute avg from smaller sum
sum1=0. sum1=0.
do i=-ia,ia do i=-ia,ia

View File

@ -15,7 +15,8 @@ subroutine foxgen()
! common block. ! common block.
parameter (NN=79,ND=58,NSPS=4*1920) parameter (NN=79,ND=58,NSPS=4*1920)
parameter (NWAVE=14278656,NFFT=614400,NH=NFFT/2) parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST240-1800 at 48kHz)
parameter (NFFT=614400,NH=NFFT/2)
character*40 cmsg character*40 cmsg
character*37 msg,msgsent character*37 msg,msgsent
integer itone(79) integer itone(79)

View File

@ -1,7 +1,7 @@
subroutine foxgen_wrap(msg40,msgbits,itone) subroutine foxgen_wrap(msg40,msgbits,itone)
parameter (NN=79,ND=58,KK=77,NSPS=4*1920) parameter (NN=79,ND=58,KK=77,NSPS=4*1920)
parameter (NWAVE=NN*NSPS) parameter (NWAVE=(160+2)*134400) !the biggest waveform we generate (FST240-1800)
character*40 msg40,cmsg character*40 msg40,cmsg
character*12 mycall12 character*12 mycall12

View File

@ -353,14 +353,41 @@ int main(int argc, char *argv[])
// Multiple instances: use rig_name as shared memory key // Multiple instances: use rig_name as shared memory key
mem_jt9.setKey(a.applicationName ()); mem_jt9.setKey(a.applicationName ());
if(!mem_jt9.attach()) { // try and shut down any orphaned jt9 process
if (!mem_jt9.create(sizeof(struct dec_data))) { for (int i = 3; i; --i) // three tries to close old jt9
splash.hide (); {
MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"), if (mem_jt9.attach ()) // shared memory presence implies
a.translate ("main", "Unable to create shared memory segment")); // orphaned jt9 sub-process
throw std::runtime_error {"Shared memory error"}; {
dec_data_t * dd = reinterpret_cast<dec_data_t *> (mem_jt9.data());
mem_jt9.lock ();
dd->ipc[1] = 999; // tell jt9 to shut down
mem_jt9.unlock ();
mem_jt9.detach (); // start again
}
else
{
break; // good to go
}
QThread::sleep (1); // wait for jt9 to end
}
if (!mem_jt9.attach ())
{
if (!mem_jt9.create (sizeof (struct dec_data)))
{
splash.hide ();
MessageBox::critical_message (nullptr, a.translate ("main", "Shared memory error"),
a.translate ("main", "Unable to create shared memory segment"));
throw std::runtime_error {"Shared memory error"};
}
}
else
{
splash.hide ();
MessageBox::critical_message (nullptr, a.translate ("main", "Sub-process error"),
a.translate ("main", "Failed to close orphaned jt9 process"));
throw std::runtime_error {"Sub-process error"};
} }
}
mem_jt9.lock (); mem_jt9.lock ();
memset(mem_jt9.data(),0,sizeof(struct dec_data)); //Zero all decoding params in shared memory memset(mem_jt9.data(),0,sizeof(struct dec_data)); //Zero all decoding params in shared memory
mem_jt9.unlock (); mem_jt9.unlock ();

View File

@ -428,7 +428,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this});
ui->dxCallEntry->setValidator (new CallsignValidator {this}); ui->dxCallEntry->setValidator (new CallsignValidator {this});
ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300}); ui->sbTR->values ({5, 10, 15, 30, 60, 120, 300});
ui->sbTR_FST240W->values ({15, 30, 60, 120, 300}); ui->sbTR_FST240W->values ({15, 30, 60, 120, 300, 900, 1800});
ui->decodedTextBrowser->set_configuration (&m_config, true); ui->decodedTextBrowser->set_configuration (&m_config, true);
ui->decodedTextBrowser2->set_configuration (&m_config); ui->decodedTextBrowser2->set_configuration (&m_config);
@ -3556,6 +3556,8 @@ void MainWindow::guiUpdate()
if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0; if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0;
if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0; if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0;
if(m_TRperiod==300) txDuration=1.0 + 160*21504/12000.0; if(m_TRperiod==300) txDuration=1.0 + 160*21504/12000.0;
if(m_TRperiod==900) txDuration=1.0 + 160*66560/12000.0;
if(m_TRperiod==1800) txDuration=1.0 + 160*134400/12000.0;
} }
if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) { if(m_modeTx=="ISCAT" or m_mode=="MSK144" or m_bFast9) {
txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144 txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, MSK144
@ -3888,6 +3890,8 @@ void MainWindow::guiUpdate()
if(m_TRperiod==60) nsps=3888; if(m_TRperiod==60) nsps=3888;
if(m_TRperiod==120) nsps=8200; if(m_TRperiod==120) nsps=8200;
if(m_TRperiod==300) nsps=21504; if(m_TRperiod==300) nsps=21504;
if(m_TRperiod==900) nsps=66560;
if(m_TRperiod==1800) nsps=134400;
nsps=4*nsps; //48000 Hz sampling nsps=4*nsps; //48000 Hz sampling
int nsym=160; int nsym=160;
float fsample=48000.0; float fsample=48000.0;
@ -5838,7 +5842,7 @@ void MainWindow::on_actionFST240_triggered()
// 0123456789012345678901234567890123 // 0123456789012345678901234567890123
displayWidgets(nWidgets("1111110001001111000100000001000000")); displayWidgets(nWidgets("1111110001001111000100000001000000"));
setup_status_bar (bVHF); setup_status_bar (bVHF);
ui->sbTR->values ({15, 30, 60, 120, 300}); ui->sbTR->values ({15, 30, 60, 120, 300, 900, 1800});
on_sbTR_valueChanged (ui->sbTR->value()); on_sbTR_valueChanged (ui->sbTR->value());
ui->cbAutoSeq->setChecked(true); ui->cbAutoSeq->setChecked(true);
m_wideGraph->setMode(m_mode); m_wideGraph->setMode(m_mode);
@ -7183,6 +7187,8 @@ void MainWindow::transmit (double snr)
if(m_TRperiod==60) nsps=3888; if(m_TRperiod==60) nsps=3888;
if(m_TRperiod==120) nsps=8200; if(m_TRperiod==120) nsps=8200;
if(m_TRperiod==300) nsps=21504; if(m_TRperiod==300) nsps=21504;
if(m_TRperiod==900) nsps=66560;
if(m_TRperiod==1800) nsps=134400;
int hmod=int(pow(2.0,double(m_nSubMode))); int hmod=int(pow(2.0,double(m_nSubMode)));
double dfreq=hmod*12000.0/nsps; double dfreq=hmod*12000.0/nsps;
double f0=ui->WSPRfreqSpinBox->value() - m_XIT + 1.5*dfreq; double f0=ui->WSPRfreqSpinBox->value() - m_XIT + 1.5*dfreq;

View File

@ -420,6 +420,8 @@ void CPlotter::DrawOverlay() //DrawOverlay()
if(m_TRperiod==60) nsps=4000; if(m_TRperiod==60) nsps=4000;
if(m_TRperiod==120) nsps=8400; if(m_TRperiod==120) nsps=8400;
if(m_TRperiod==300) nsps=21504; if(m_TRperiod==300) nsps=21504;
if(m_TRperiod==900) nsps=66560;
if(m_TRperiod==1800) nsps=134400;
float baud=12000.0/nsps; float baud=12000.0/nsps;
bw=3.0*h*baud; bw=3.0*h*baud;
} }