Merged master 8748
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
program ft8sim
|
||||
|
||||
! Generate simulated data for a 15-second HF/6m mode using 8-FSK.
|
||||
! Output is saved to a *.wav file.
|
||||
|
||||
use wavhdr
|
||||
include 'ft8_params.f90' !Set various constants
|
||||
parameter (NWAVE=NN*NSPS)
|
||||
type(hdr) h !Header for .wav file
|
||||
character arg*12,fname*17
|
||||
character msg40*40,msg*22,msgsent*22,msg0*22
|
||||
character*6 mygrid6
|
||||
logical bcontest
|
||||
complex c0(0:NMAX-1)
|
||||
complex c(0:NMAX-1)
|
||||
real wave(NMAX)
|
||||
integer itone(NN)
|
||||
integer*1 msgbits(KK)
|
||||
integer*2 iwave(NMAX) !Generated full-length waveform
|
||||
data mygrid6/'EM48 '/
|
||||
|
||||
! Get command-line argument(s)
|
||||
nargs=iargc()
|
||||
if(nargs.ne.8) then
|
||||
print*,'Usage: ft8sim "message" nsig|f0 DT fdop del width nfiles snr'
|
||||
print*,'Examples: ft8sim "K1ABC W9XYZ EN37" 1500.0 0.0 0.1 1.0 0 10 -18'
|
||||
print*,' ft8sim "K1ABC W9XYZ EN37" 10 0.0 0.1 1.0 25 10 -18'
|
||||
print*,' ft8sim "K1ABC W9XYZ EN37" 25 0.0 0.1 1.0 25 10 -18'
|
||||
print*,' ft8sim "K1ABC RR73; W9XYZ <KH1/KH7Z> -11" 300 0 0 0 25 1 -10'
|
||||
print*,'Make nfiles negative to invoke 72-bit contest mode.'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,msg40) !Message to be transmitted
|
||||
call getarg(2,arg)
|
||||
read(arg,*) f0 !Frequency (only used for single-signal)
|
||||
call getarg(3,arg)
|
||||
read(arg,*) xdt !Time offset from nominal (s)
|
||||
call getarg(4,arg)
|
||||
read(arg,*) fspread !Watterson frequency spread (Hz)
|
||||
call getarg(5,arg)
|
||||
read(arg,*) delay !Watterson delay (ms)
|
||||
call getarg(6,arg)
|
||||
read(arg,*) width !Filter transition width (Hz)
|
||||
call getarg(7,arg)
|
||||
read(arg,*) nfiles !Number of files
|
||||
call getarg(8,arg)
|
||||
read(arg,*) snrdb !SNR_2500
|
||||
nsig=1
|
||||
if(f0.lt.100.0) then
|
||||
nsig=f0
|
||||
f0=1500
|
||||
endif
|
||||
|
||||
bcontest=nfiles.lt.0
|
||||
nfiles=abs(nfiles)
|
||||
twopi=8.0*atan(1.0)
|
||||
fs=12000.0 !Sample rate (Hz)
|
||||
dt=1.0/fs !Sample interval (s)
|
||||
tt=NSPS*dt !Duration of symbols (s)
|
||||
baud=1.0/tt !Keying rate (baud)
|
||||
bw=8*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
|
||||
txt=NN*NSPS/12000.0
|
||||
|
||||
! Source-encode, then get itone()
|
||||
if(index(msg40,';').le.0) then
|
||||
i3bit=0
|
||||
msg=msg40(1:22)
|
||||
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
write(*,1000) f0,xdt,txt,snrdb,bw,msgsent
|
||||
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
|
||||
' BW:',f4.1,2x,a22)
|
||||
else
|
||||
call foxgen_wrap(msg40,msgbits,itone)
|
||||
write(*,1001) f0,xdt,txt,snrdb,bw,msg40
|
||||
1001 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
|
||||
' BW:',f4.1,2x,a40)
|
||||
endif
|
||||
|
||||
write(*,1030) msgbits(1:56)
|
||||
1030 format(/'Call1: ',28i1,' Call2: ',28i1)
|
||||
write(*,1032) msgbits(57:72),msgbits(73:75),msgbits(76:87)
|
||||
1032 format('Grid: ',16i1,' 3Bit: ',3i1,' CRC12: ',12i1)
|
||||
write(*,1034) itone
|
||||
1034 format(/'Channel symbols:'/79i1/)
|
||||
|
||||
msg0=msg
|
||||
do ifile=1,nfiles
|
||||
c=0.
|
||||
do isig=1,nsig
|
||||
c0=0.
|
||||
if(nsig.eq.2) then
|
||||
if(index(msg,'R-').gt.0) f0=500
|
||||
i1=index(msg,' ')
|
||||
msg(i1+4:i1+4)=char(ichar('A')+isig-1)
|
||||
if(isig.eq.2) then
|
||||
f0=f0+100
|
||||
endif
|
||||
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
endif
|
||||
if(nsig.eq.25) then
|
||||
f0=(isig+2)*100.0
|
||||
else if(nsig.eq.50) then
|
||||
msg=msg0
|
||||
f0=1000.0 + (isig-1)*60.0
|
||||
i1=index(msg,' ')
|
||||
i2=index(msg(i1+1:),' ') + i1
|
||||
msg(i1+2:i1+2)=char(ichar('0')+mod(isig-1,10))
|
||||
msg(i1+3:i1+3)=char(ichar('A')+mod(isig-1,26))
|
||||
msg(i1+4:i1+4)=char(ichar('A')+mod(isig-1,26))
|
||||
msg(i1+5:i1+5)=char(ichar('A')+mod(isig-1,26))
|
||||
write(msg(i2+3:i2+4),'(i2.2)') isig-1
|
||||
if(ifile.ge.2 .and. isig.eq.ifile-1) then
|
||||
write(msg(i2+1:i2+4),1002) -isig
|
||||
1002 format('R',i3.2)
|
||||
f0=600.0 + mod(isig-1,5)*60.0
|
||||
endif
|
||||
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
endif
|
||||
k=-1 + nint((xdt+0.5+0.01*gran())/dt)
|
||||
! k=-1 + nint((xdt+0.5)/dt)
|
||||
ia=k+1
|
||||
phi=0.0
|
||||
do j=1,NN !Generate complex waveform
|
||||
dphi=twopi*(f0+itone(j)*baud)*dt
|
||||
do i=1,NSPS
|
||||
k=k+1
|
||||
phi=mod(phi+dphi,twopi)
|
||||
if(k.ge.0 .and. k.lt.NMAX) c0(k)=cmplx(cos(phi),sin(phi))
|
||||
enddo
|
||||
enddo
|
||||
if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c0,NMAX,fs,delay,fspread)
|
||||
c=c+sig*c0
|
||||
enddo
|
||||
ib=k
|
||||
wave=real(c)
|
||||
peak=maxval(abs(wave(ia:ib)))
|
||||
rms=sqrt(dot_product(wave(ia:ib),wave(ia:ib))/NWAVE)
|
||||
nslots=1
|
||||
if(width.gt.0.0) call filt8(f0,nslots,width,wave)
|
||||
|
||||
if(snrdb.lt.90) then
|
||||
do i=1,NMAX !Add gaussian noise at specified SNR
|
||||
xnoise=gran()
|
||||
! wave(i)=wave(i) + xnoise
|
||||
! if(i.ge.ia .and. i.le.ib) write(30,3001) i,wave(i)/peak
|
||||
!3001 format(i8,f12.6)
|
||||
wave(i)=wave(i) + xnoise
|
||||
enddo
|
||||
endif
|
||||
|
||||
fac=32767.0
|
||||
rms=100.0
|
||||
if(snrdb.ge.90.0) iwave(1:NMAX)=nint(fac*wave)
|
||||
if(snrdb.lt.90.0) iwave(1:NMAX)=nint(rms*wave)
|
||||
|
||||
h=default_header(12000,NMAX)
|
||||
write(fname,1102) ifile
|
||||
1102 format('000000_',i6.6,'.wav')
|
||||
open(10,file=fname,status='unknown',access='stream')
|
||||
write(10) h,iwave !Save to *.wav file
|
||||
close(10)
|
||||
write(*,1110) ifile,xdt,f0,snrdb,fname
|
||||
1110 format(i4,f7.2,f8.2,f7.1,2x,a17)
|
||||
enddo
|
||||
|
||||
999 end program ft8sim
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
0; 0; 0
|
||||
0; 0; 9
|
||||
0; 0; 21
|
||||
0; 0; 34
|
||||
0; 0; 45
|
||||
0; 0; 57
|
||||
0; 0; 67
|
||||
0; 0; 77
|
||||
0; 0; 86
|
||||
0; 0; 94
|
||||
0; 12;101
|
||||
0; 23;106
|
||||
0; 35;110
|
||||
0; 46;113
|
||||
0; 57;115
|
||||
0; 68;115
|
||||
0; 78;114
|
||||
0; 88;112
|
||||
0; 97;108
|
||||
0;106;103
|
||||
0;114; 97
|
||||
0;122; 90
|
||||
0;129; 81
|
||||
0;136; 72
|
||||
0;141; 62
|
||||
0;146; 51
|
||||
0;151; 39
|
||||
11;154; 27
|
||||
29;157; 15
|
||||
46;158; 2
|
||||
63;159; 0
|
||||
79;159; 0
|
||||
96;159; 0
|
||||
111;157; 0
|
||||
127;155; 0
|
||||
142;152; 0
|
||||
156;148; 0
|
||||
169;143; 0
|
||||
182;138; 0
|
||||
193;131; 0
|
||||
204;124; 0
|
||||
214;117; 0
|
||||
223;109; 0
|
||||
231;100; 0
|
||||
238; 91; 0
|
||||
244; 81; 0
|
||||
248; 71; 0
|
||||
252; 60; 5
|
||||
254; 50; 19
|
||||
255; 38; 33
|
||||
255; 47; 47
|
||||
255; 61; 61
|
||||
255; 75; 75
|
||||
255; 90; 90
|
||||
255;105;105
|
||||
255;121;121
|
||||
255;138;138
|
||||
255;156;156
|
||||
255;175;175
|
||||
255;196;196
|
||||
255;218;218
|
||||
255;243;243
|
||||
255;255;255
|
||||
255;255;255
|
||||
255;255;255
|
||||
Binary file not shown.
@@ -1,115 +0,0 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef WIDEGRAPH_H
|
||||
#define WIDEGRAPH_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include <QDir>
|
||||
#include <QHash>
|
||||
#include <QVariant>
|
||||
#include "WFPalette.hpp"
|
||||
|
||||
#define MAX_SCREENSIZE 2048
|
||||
|
||||
namespace Ui {
|
||||
class WideGraph;
|
||||
}
|
||||
|
||||
class QSettings;
|
||||
class Configuration;
|
||||
|
||||
class WideGraph : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WideGraph(QSettings *, QWidget *parent = 0);
|
||||
~WideGraph ();
|
||||
|
||||
void dataSink2(float s[], float df3, int ihsym, int ndiskdata);
|
||||
void setRxFreq(int n);
|
||||
int rxFreq();
|
||||
int nStartFreq();
|
||||
int Fmin();
|
||||
int Fmax();
|
||||
int fSpan();
|
||||
void saveSettings();
|
||||
void setFsample(int n);
|
||||
void setPeriod(int ntrperiod, int nsps);
|
||||
void setTxFreq(int n);
|
||||
void setMode(QString mode);
|
||||
void setSubMode(int n);
|
||||
void setModeTx(QString modeTx);
|
||||
bool flatten();
|
||||
bool useRef();
|
||||
void setTol(int n);
|
||||
int smoothYellow();
|
||||
void setRxBand (QString const& band);
|
||||
void setWSPRtransmitted();
|
||||
void drawRed(int ia, int ib);
|
||||
void setVHF(bool bVHF);
|
||||
void setRedFile(QString fRed);
|
||||
|
||||
signals:
|
||||
void freezeDecode2(int n);
|
||||
void f11f12(int n);
|
||||
void setXIT2(int n);
|
||||
void setFreq3(int rxFreq, int txFreq);
|
||||
|
||||
public slots:
|
||||
void wideFreezeDecode(int n);
|
||||
void setFreq2(int rxFreq, int txFreq);
|
||||
void setDialFreq(double d);
|
||||
|
||||
protected:
|
||||
void keyPressEvent (QKeyEvent *e) override;
|
||||
void closeEvent (QCloseEvent *) override;
|
||||
|
||||
private slots:
|
||||
void on_waterfallAvgSpinBox_valueChanged(int arg1);
|
||||
void on_bppSpinBox_valueChanged(int arg1);
|
||||
void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
|
||||
void on_fSplitSpinBox_valueChanged(int n);
|
||||
void on_fStartSpinBox_valueChanged(int n);
|
||||
void on_paletteComboBox_activated(const QString &palette);
|
||||
void on_cbFlatten_toggled(bool b);
|
||||
void on_cbRef_toggled(bool b);
|
||||
void on_cbControls_toggled(bool b);
|
||||
void on_adjust_palette_push_button_clicked (bool);
|
||||
void on_gainSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_gain2dSlider_valueChanged(int value);
|
||||
void on_zero2dSlider_valueChanged(int value);
|
||||
void on_smoSpinBox_valueChanged(int n);
|
||||
void on_sbPercent2dPlot_valueChanged(int n);
|
||||
|
||||
private:
|
||||
void readPalette ();
|
||||
void setRxRange ();
|
||||
|
||||
QScopedPointer<Ui::WideGraph> ui;
|
||||
|
||||
QSettings * m_settings;
|
||||
QDir m_palettes_path;
|
||||
WFPalette m_userPalette;
|
||||
|
||||
qint32 m_waterfallAvg;
|
||||
qint32 m_TRperiod;
|
||||
qint32 m_nsps;
|
||||
qint32 m_ntr0;
|
||||
QHash<QString, QVariant> m_fMinPerBand;
|
||||
qint32 m_fMax;
|
||||
QString m_rxBand;
|
||||
qint32 m_nSubMode;
|
||||
qint32 m_nsmo;
|
||||
qint32 m_Percent2DScreen;
|
||||
bool m_bFlatten;
|
||||
bool m_bRef;
|
||||
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
QString m_waterfallPalette;
|
||||
int m_n;
|
||||
};
|
||||
|
||||
#endif // WIDEGRAPH_H
|
||||
@@ -1,367 +0,0 @@
|
||||
subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
||||
lsubtract,nagain,iaptype,mygrid6,bcontest,sync0,f1,xdt,xbase,apsym, &
|
||||
nharderrors,dmin,nbadcrc,ipass,iera,message,xsnr)
|
||||
|
||||
use timer_module, only: timer
|
||||
include 'ft8_params.f90'
|
||||
parameter(NRECENT=10,NP2=2812)
|
||||
character message*22,msgsent*22
|
||||
character*12 recent_calls(NRECENT)
|
||||
character*6 mygrid6
|
||||
logical bcontest
|
||||
real a(5)
|
||||
real s1(0:7,ND),s2(0:7,NN)
|
||||
real ps(0:7)
|
||||
real bmeta(3*ND),bmetap(3*ND)
|
||||
real llr(3*ND),llra(3*ND),llr0(3*ND),llrap(3*ND) !Soft symbols
|
||||
real dd0(15*12000)
|
||||
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
|
||||
integer*1 msgbits(KK)
|
||||
integer apsym(KK)
|
||||
integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
|
||||
integer itone(NN)
|
||||
integer icos7(0:6),ip(1)
|
||||
integer nappasses(0:5) ! the number of decoding passes to use for each QSO state
|
||||
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
|
||||
complex cd0(3200)
|
||||
complex ctwk(32)
|
||||
complex csymb(32)
|
||||
logical first,newdat,lsubtract,lapon,nagain
|
||||
data icos7/2,5,6,0,4,1,3/
|
||||
data mcq/1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1/
|
||||
data mrrr/0,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1/
|
||||
data m73/0,1,1,1,1,1,1,0,1,1,0,1,0,0,0,0/
|
||||
data mde/1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,0,1/
|
||||
data mrr73/0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1/
|
||||
data first/.true./
|
||||
save nappasses,naptypes
|
||||
|
||||
if(first) then
|
||||
mcq=2*mcq-1
|
||||
mde=2*mde-1
|
||||
mrrr=2*mrrr-1
|
||||
m73=2*m73-1
|
||||
mrr73=2*mrr73-1
|
||||
nappasses(0)=2
|
||||
nappasses(1)=2
|
||||
nappasses(2)=2
|
||||
nappasses(3)=4
|
||||
nappasses(4)=4
|
||||
nappasses(5)=3
|
||||
|
||||
! iaptype
|
||||
!------------------------
|
||||
! 1 CQ ??? ???
|
||||
! 2 MyCall ??? ???
|
||||
! 3 MyCall DxCall ???
|
||||
! 4 MyCall DxCall RRR
|
||||
! 5 MyCall DxCall 73
|
||||
! 6 MyCall DxCall RR73
|
||||
! 7 ??? DxCall ???
|
||||
|
||||
naptypes(0,1:4)=(/1,2,0,0/)
|
||||
naptypes(1,1:4)=(/2,3,0,0/)
|
||||
naptypes(2,1:4)=(/2,3,0,0/)
|
||||
naptypes(3,1:4)=(/3,4,5,6/)
|
||||
naptypes(4,1:4)=(/3,4,5,6/)
|
||||
naptypes(5,1:4)=(/3,1,2,0/) !?
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
max_iterations=30
|
||||
nharderrors=-1
|
||||
fs2=12000.0/NDOWN
|
||||
dt2=1.0/fs2
|
||||
twopi=8.0*atan(1.0)
|
||||
delfbest=0.
|
||||
ibest=0
|
||||
|
||||
call timer('ft8_down',0)
|
||||
call ft8_downsample(dd0,newdat,f1,cd0) !Mix f1 to baseband and downsample
|
||||
call timer('ft8_down',1)
|
||||
|
||||
i0=nint((xdt+0.5)*fs2) !Initial guess for start of signal
|
||||
smax=0.0
|
||||
do idt=i0-8,i0+8 !Search over +/- one quarter symbol
|
||||
call sync8d(cd0,idt,ctwk,0,sync)
|
||||
if(sync.gt.smax) then
|
||||
smax=sync
|
||||
ibest=idt
|
||||
endif
|
||||
enddo
|
||||
xdt2=ibest*dt2 !Improved estimate for DT
|
||||
|
||||
! Now peak up in frequency
|
||||
i0=nint(xdt2*fs2)
|
||||
smax=0.0
|
||||
do ifr=-5,5 !Search over +/- 2.5 Hz
|
||||
delf=ifr*0.5
|
||||
dphi=twopi*delf*dt2
|
||||
phi=0.0
|
||||
do i=1,32
|
||||
ctwk(i)=cmplx(cos(phi),sin(phi))
|
||||
phi=mod(phi+dphi,twopi)
|
||||
enddo
|
||||
call sync8d(cd0,i0,ctwk,1,sync)
|
||||
if( sync .gt. smax ) then
|
||||
smax=sync
|
||||
delfbest=delf
|
||||
endif
|
||||
enddo
|
||||
a=0.0
|
||||
a(1)=-delfbest
|
||||
call twkfreq1(cd0,NP2,fs2,a,cd0)
|
||||
xdt=xdt2
|
||||
f1=f1+delfbest !Improved estimate of DF
|
||||
|
||||
call sync8d(cd0,i0,ctwk,2,sync)
|
||||
|
||||
j=0
|
||||
do k=1,NN
|
||||
i1=ibest+(k-1)*32
|
||||
csymb=cmplx(0.0,0.0)
|
||||
if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
|
||||
call four2a(csymb,32,1,-1,1)
|
||||
s2(0:7,k)=abs(csymb(1:8))/1e3
|
||||
enddo
|
||||
|
||||
! sync quality check
|
||||
is1=0
|
||||
is2=0
|
||||
is3=0
|
||||
do k=1,7
|
||||
ip=maxloc(s2(:,k))
|
||||
if(icos7(k-1).eq.(ip(1)-1)) is1=is1+1
|
||||
ip=maxloc(s2(:,k+36))
|
||||
if(icos7(k-1).eq.(ip(1)-1)) is2=is2+1
|
||||
ip=maxloc(s2(:,k+72))
|
||||
if(icos7(k-1).eq.(ip(1)-1)) is3=is3+1
|
||||
enddo
|
||||
! hard sync sum - max is 21
|
||||
nsync=is1+is2+is3
|
||||
if(nsync .le. 6) then ! bail out
|
||||
nbadcrc=1
|
||||
return
|
||||
endif
|
||||
|
||||
j=0
|
||||
do k=1,NN
|
||||
if(k.le.7) cycle
|
||||
if(k.ge.37 .and. k.le.43) cycle
|
||||
if(k.gt.72) cycle
|
||||
j=j+1
|
||||
s1(0:7,j)=s2(0:7,k)
|
||||
enddo
|
||||
|
||||
do j=1,ND
|
||||
i4=3*j-2
|
||||
i2=3*j-1
|
||||
i1=3*j
|
||||
ps=s1(0:7,j)
|
||||
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
|
||||
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
|
||||
r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
|
||||
bmeta(i4)=r4
|
||||
bmeta(i2)=r2
|
||||
bmeta(i1)=r1
|
||||
bmetap(i4)=r4
|
||||
bmetap(i2)=r2
|
||||
bmetap(i1)=r1
|
||||
|
||||
if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
|
||||
! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
|
||||
! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
|
||||
if(j.eq.39) then ! take care of bits that live in symbol 39
|
||||
if(apsym(28).lt.0) then
|
||||
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
|
||||
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
|
||||
else
|
||||
bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
|
||||
bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
|
||||
! with ap bits 116 and 117. Take care of metric for bit 115.
|
||||
! if(j.eq.39) then ! take care of bit 115
|
||||
! iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
|
||||
! if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
|
||||
! if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
|
||||
! if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
|
||||
! if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
|
||||
! endif
|
||||
|
||||
! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
|
||||
! take care of metrics for bits 142 and 143
|
||||
if(j.eq.48) then ! bit 144 is always 1
|
||||
bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
|
||||
bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
|
||||
endif
|
||||
|
||||
! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
|
||||
! take care of metrics for bits 155 and 156
|
||||
if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
|
||||
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
|
||||
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
||||
call normalizebmet(bmeta,3*ND)
|
||||
call normalizebmet(bmetap,3*ND)
|
||||
|
||||
ss=0.84
|
||||
llr0=2.0*bmeta/(ss*ss)
|
||||
llra=2.0*bmetap/(ss*ss) ! llr's for use with ap
|
||||
apmag=4.0
|
||||
|
||||
! pass #
|
||||
!------------------------------
|
||||
! 1 regular decoding
|
||||
! 2 erase 24
|
||||
! 3 erase 48
|
||||
! 4 ap pass 1
|
||||
! 5 ap pass 2
|
||||
! 6 ap pass 3
|
||||
! 7 ap pass 4, etc.
|
||||
|
||||
if(lapon) then
|
||||
npasses=3+nappasses(nQSOProgress)
|
||||
else
|
||||
npasses=3
|
||||
endif
|
||||
|
||||
do ipass=1,npasses
|
||||
|
||||
llr=llr0
|
||||
if(ipass.eq.2) llr(1:24)=0.
|
||||
if(ipass.eq.3) llr(1:48)=0.
|
||||
if(ipass.le.3) then
|
||||
apmask=0
|
||||
llrap=llr
|
||||
iaptype=0
|
||||
endif
|
||||
|
||||
if(ipass .gt. 3) then
|
||||
iaptype=naptypes(nQSOProgress,ipass-3)
|
||||
if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
|
||||
if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
|
||||
apmask=0
|
||||
apmask(88:115)=1 ! first 28 bits are AP
|
||||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
if(iaptype.eq.1) llrap(88:115)=apmag*mcq/ss
|
||||
if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)/ss
|
||||
llrap(116:117)=llra(116:117)
|
||||
llrap(142:143)=llra(142:143)
|
||||
llrap(144)=-apmag/ss
|
||||
endif
|
||||
if(iaptype.eq.3) then ! mycall, dxcall, ???
|
||||
apmask=0
|
||||
apmask(88:115)=1 ! mycall
|
||||
apmask(116:143)=1 ! hiscall
|
||||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
llrap(88:143)=apmag*apsym(1:56)/ss
|
||||
llrap(144)=-apmag/ss
|
||||
endif
|
||||
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
|
||||
apmask=0
|
||||
apmask(88:115)=1 ! mycall
|
||||
apmask(116:143)=1 ! hiscall
|
||||
apmask(144:159)=1 ! RRR or 73 or RR73
|
||||
llrap=llr
|
||||
llrap(88:143)=apmag*apsym(1:56)/ss
|
||||
if(iaptype.eq.4) llrap(144:159)=apmag*mrrr/ss
|
||||
if(iaptype.eq.5) llrap(144:159)=apmag*m73/ss
|
||||
if(iaptype.eq.6) llrap(144:159)=apmag*mrr73/ss
|
||||
endif
|
||||
if(iaptype.eq.7) then ! ???, dxcall, ???
|
||||
apmask=0
|
||||
apmask(116:143)=1 ! hiscall
|
||||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
llrap(115)=llra(115)
|
||||
llrap(116:143)=apmag*apsym(29:56)/ss
|
||||
llrap(144)=-apmag/ss
|
||||
endif
|
||||
endif
|
||||
|
||||
cw=0
|
||||
call timer('bpd174 ',0)
|
||||
call bpdecode174(llrap,apmask,max_iterations,decoded,cw,nharderrors, &
|
||||
niterations)
|
||||
call timer('bpd174 ',1)
|
||||
dmin=0.0
|
||||
if(ndepth.eq.3 .and. nharderrors.lt.0) then
|
||||
ndeep=3
|
||||
if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
|
||||
if((ipass.eq.2 .or. ipass.eq.3) .and. .not.nagain) then
|
||||
ndeep=3
|
||||
else
|
||||
ndeep=4
|
||||
endif
|
||||
endif
|
||||
if(nagain) ndeep=5
|
||||
call timer('osd174 ',0)
|
||||
call osd174(llrap,apmask,ndeep,decoded,cw,nharderrors,dmin)
|
||||
call timer('osd174 ',1)
|
||||
endif
|
||||
nbadcrc=1
|
||||
message=' '
|
||||
xsnr=-99.0
|
||||
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
|
||||
if(any(decoded(73:75).ne.0)) cycle !Reject if any of the 3 extra bits are nonzero
|
||||
if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
|
||||
.not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
|
||||
.not.(ipass.gt.1 .and. nharderrors.gt.39) .and. &
|
||||
.not.(ipass.eq.3 .and. nharderrors.gt.30) &
|
||||
) then
|
||||
call chkcrc12a(decoded,nbadcrc)
|
||||
else
|
||||
nharderrors=-1
|
||||
cycle
|
||||
endif
|
||||
if(nbadcrc.eq.0) then
|
||||
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
|
||||
call genft8(message,mygrid6,bcontest,msgsent,msgbits,itone)
|
||||
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
|
||||
xsig=0.0
|
||||
xnoi=0.0
|
||||
do i=1,79
|
||||
xsig=xsig+s2(itone(i),i)**2
|
||||
ios=mod(itone(i)+4,7)
|
||||
xnoi=xnoi+s2(ios,i)**2
|
||||
enddo
|
||||
xsnr=0.001
|
||||
if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0
|
||||
xsnr=10.0*log10(xsnr)-27.0
|
||||
!###
|
||||
xsnr2=db(xsig/xbase - 1.0) - 32.0
|
||||
! write(52,3052) f1,xdt,xsig,xnoi,xbase,xsnr,xsnr2
|
||||
!3052 format(7f10.2)
|
||||
xsnr=xsnr2
|
||||
!###
|
||||
if(xsnr .lt. -24.0) xsnr=-24.0
|
||||
return
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine ft8b
|
||||
|
||||
subroutine normalizebmet(bmet,n)
|
||||
real bmet(n)
|
||||
|
||||
bmetav=sum(bmet)/real(n)
|
||||
bmet2av=sum(bmet*bmet)/real(n)
|
||||
var=bmet2av-bmetav*bmetav
|
||||
if( var .gt. 0.0 ) then
|
||||
bmetsig=sqrt(var)
|
||||
else
|
||||
bmetsig=sqrt(bmet2av)
|
||||
endif
|
||||
bmet=bmet/bmetsig
|
||||
return
|
||||
end subroutine normalizebmet
|
||||
Reference in New Issue
Block a user