mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-12-23 19:25:37 -05:00
Code cleanup. Implement use of fQSO, ntol, etc.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@2671 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
2a11cd7c5e
commit
dd0fb0c743
@ -12,10 +12,10 @@ extern struct {
|
||||
int nutc; //UTC as integer, HHMM
|
||||
int ndiskdat; //1 ==> data read from *.wav file
|
||||
int ntrperiod; //TR period (seconds)
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nfqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int npts8; //npts for c0() array
|
||||
int nfb; //High decode limit (kHz)
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int kin;
|
||||
|
18
jt9.txt
18
jt9.txt
@ -1,7 +1,7 @@
|
||||
JT9 is a mode designed for amateur QSOs at MF and LF. The mode uses
|
||||
the same 72-bit structured messages as JT65. Error control coding
|
||||
(ECC) uses a convolutional code with constraint length K=32, rate
|
||||
r=1/2, and a zero tail, leading to an encoded message length of
|
||||
(ECC) uses a strong convolutional code with constraint length K=32,
|
||||
rate r=1/2, and a zero tail, leading to an encoded message length of
|
||||
(72+31)*2 = 206 information-carrying bits. Modulation is 9-FSK: 8
|
||||
tones for data, one for synchronization. Sixteen symbol intervals are
|
||||
used for synchronization, so a transmission requires a total of 207/3
|
||||
@ -10,12 +10,14 @@ used for synchronization, so a transmission requires a total of 207/3
|
||||
Exact symbol lengths are chosen so that nsps, the number of samples
|
||||
per symbol (at 12000 samples per second) is a number with no prime
|
||||
factor greater than 7. This choice makes for efficient FFTs. Tone
|
||||
spacing of the 9-FSK modulation is df=1/tsym=12000/nsps, equal to
|
||||
the keying rate. The total occupied bandwidth is 9*df.
|
||||
spacing of the 9-FSK modulation is df=1/tsym=12000/nsps, equal to the
|
||||
keying rate. The total occupied bandwidth is 9*df. The generated
|
||||
signal has continuous phase, and there are no key clicks.
|
||||
|
||||
Parameters of five JT9 sub-modes are summarized in the following
|
||||
table, along with S/N thresholds measured by simulation on an AWGN
|
||||
channel.
|
||||
channel. Numbers following "JT9-" in the sub-mode names specify the
|
||||
T/R period in minutes.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Mode nsps nsps2 df tsym BW S/N* Tdec Tfree Factors
|
||||
@ -46,12 +48,12 @@ Receiving
|
||||
2. Filter to 1000 Hz bandwidth and downsample (1/8) to 1500 Hz, saving
|
||||
complex data to array c0(2,700,000).
|
||||
3. Compute spectra at half-symbol steps. Use for waterfall display
|
||||
s(22000) and save in ss(184,22000) and
|
||||
savg(22000), for detecting sync vectors.
|
||||
s(22000) and save in ss(184,22000) and savg(22000) for detecting
|
||||
sync vectors.
|
||||
4. At time Tdec, find sync vectors in ss(); get approx DF or list of DFs
|
||||
5. Do full-length FFT, NFFT1=96*nsps2, zero-padded as required.
|
||||
6. For each candidate signal, do inverse FFT of length 1536 (or 3072?).
|
||||
This yields 16 complex samples per symbol, and sync tone should be
|
||||
This yields 16 complex samples per symbol; sync tone should be
|
||||
close to zero frequency.
|
||||
7. Use afc65b method to get improved values of DF, DT.
|
||||
8. Tweak freq and time offset to 0.
|
||||
|
@ -14,7 +14,7 @@ subroutine decoder(ntrSeconds,c0)
|
||||
integer*2 id2
|
||||
complex c0(NDMAX)
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
ntr,mousefqso,nagain,newdat,nfa,nfb,ntol,kin
|
||||
ntr,nfqso,nagain,newdat,npts8,nfb,ntol,kin
|
||||
|
||||
ntrMinutes=ntrSeconds/60
|
||||
newdat=1
|
||||
@ -35,24 +35,22 @@ subroutine decoder(ntrSeconds,c0)
|
||||
|
||||
! Now do the decoding
|
||||
nutc=0
|
||||
kstep=nsps/2
|
||||
tstep=kstep/12000.0
|
||||
|
||||
ntol=500
|
||||
nfqso=1500
|
||||
|
||||
! Get sync, approx freq
|
||||
call sync9(ss,tstep,df3,ntol,nfqso,sync,fpk,red)
|
||||
npts8=170880 !### TEST ONLY ###
|
||||
print*,'A',nfqso,ntol,fpk
|
||||
call spec9(c0,npts8,nsps,fpk,xdt,i1SoftSymbols)
|
||||
call decode9(i1SoftSymbols,msg)
|
||||
|
||||
open(73,file='decoded.txt',status='unknown')
|
||||
rewind 73
|
||||
open(13,file='decoded.txt',status='unknown')
|
||||
rewind 13
|
||||
! write(*,1010) nutc,sync,xdt,1000.0+fpk,msg
|
||||
write(73,1010) nutc,sync,xdt,1000.0+fpk,msg
|
||||
write(13,1010) nutc,sync,xdt,1000.0+fpk,msg
|
||||
1010 format(i4.4,3f7.1,2x,a22)
|
||||
call flush(73)
|
||||
close(73)
|
||||
call flush(13)
|
||||
close(13)
|
||||
|
||||
return
|
||||
end subroutine decoder
|
||||
|
@ -2,6 +2,7 @@ subroutine spec9(c0,npts8,nsps,fpk,xdt,i1SoftSymbols)
|
||||
|
||||
parameter (MAXFFT=31500)
|
||||
complex c0(0:npts8-1)
|
||||
complex c1(0:2700000)
|
||||
real ssym(0:7,69)
|
||||
complex c(0:MAXFFT-1)
|
||||
integer*1 i1SoftSymbolsScrambled(207)
|
||||
@ -27,17 +28,17 @@ subroutine spec9(c0,npts8,nsps,fpk,xdt,i1SoftSymbols)
|
||||
phi=phi+dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
if(phi.lt.-twopi) phi=phi+twopi
|
||||
c0(i)=cmplx(aimag(c0(i)),real(c0(i)))*cmplx(cos(phi),sin(phi))
|
||||
c1(i)=cmplx(aimag(c0(i)),real(c0(i)))*cmplx(cos(phi),sin(phi))
|
||||
enddo
|
||||
|
||||
nsps8=nsps/8
|
||||
foffset=fpk
|
||||
istart=1520
|
||||
|
||||
call peakdf9(c0,npts8,nsps8,istart,foffset,idf)
|
||||
call peakdf9(c1,npts8,nsps8,istart,foffset,idf)
|
||||
fpk=fpk + idf*0.1*1500.0/nsps8
|
||||
foffset=foffset + idf*0.1*1500.0/nsps8
|
||||
call peakdt9(c0,npts8,nsps8,istart,foffset,idt)
|
||||
call peakdt9(c1,npts8,nsps8,istart,foffset,idt)
|
||||
istart=istart + 0.0625*nsps8*idt
|
||||
xdt=istart/1500.0 - 1.0
|
||||
! write(*,3002) 0.0625*nsps8*idt/1500.0,idf*0.1*1500.0/nsps8
|
||||
@ -57,7 +58,7 @@ subroutine spec9(c0,npts8,nsps,fpk,xdt,i1SoftSymbols)
|
||||
k=k+1
|
||||
ia=(j-1)*nsps8 + istart
|
||||
ib=ia+nsps8-1
|
||||
c(0:nfft-1)=c0(ia:ib)
|
||||
c(0:nfft-1)=c1(ia:ib)
|
||||
|
||||
phi=0.
|
||||
do i=0,nfft-1
|
||||
|
@ -37,7 +37,7 @@ subroutine symspec(k,ntrperiod,nsps,nb,nbslider,pxdb,s,red, &
|
||||
data rms/999.0/,k0/99999999/,ntrperiod0/0/,nfft3z/0/
|
||||
save
|
||||
|
||||
if(ntrperiod.eq.1) nfft3=1024
|
||||
if(ntrperiod.eq.1) nfft3=2048
|
||||
if(ntrperiod.eq.2) nfft3=2048
|
||||
if(ntrperiod.eq.5) nfft3=6144
|
||||
if(ntrperiod.eq.10) nfft3=12288
|
||||
|
@ -373,9 +373,9 @@ void MainWindow::dataSink(int k)
|
||||
ntr0=ntr;
|
||||
n=0;
|
||||
}
|
||||
if(ihsym == m_hsymStop) {
|
||||
jt9com_.newdat=1;
|
||||
jt9com_.nagain=0;
|
||||
// This is a bit strange. Why do we need the "-3" ??
|
||||
if(ihsym == m_hsymStop-3) {
|
||||
jt9com_.npts8=(ihsym*m_nsps)/16;
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime=t.toString("yyyy-MMM-dd hh:mm");
|
||||
decode(); //Start the decoder
|
||||
@ -509,19 +509,17 @@ void MainWindow::keyPressEvent( QKeyEvent *e ) //keyPressEvent
|
||||
case Qt::Key_F11:
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
} else {
|
||||
int n0=g_pWideGraph->DF();
|
||||
int n=(n0 + 10000) % 5;
|
||||
if(n==0) n=5;
|
||||
g_pWideGraph->setDF(n0-n);
|
||||
int n=g_pWideGraph->QSOfreq();
|
||||
n--;
|
||||
g_pWideGraph->setQSOfreq(n);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_F12:
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
} else {
|
||||
int n0=g_pWideGraph->DF();
|
||||
int n=(n0 + 10000) % 5;
|
||||
if(n==0) n=5;
|
||||
g_pWideGraph->setDF(n0+n);
|
||||
int n=g_pWideGraph->QSOfreq();
|
||||
n++;
|
||||
g_pWideGraph->setQSOfreq(n);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_G:
|
||||
@ -726,10 +724,12 @@ void MainWindow::on_actionDecode_remaining_files_in_directory_triggered()
|
||||
|
||||
void MainWindow::diskDat() //diskDat()
|
||||
{
|
||||
int k;
|
||||
int kstep=m_nsps/2;
|
||||
m_diskData=true;
|
||||
for(int n=1; n<=m_hsymStop; n++) { // Do the half-symbol FFTs
|
||||
int k=(n+1)*kstep;
|
||||
k=(n+1)*kstep;
|
||||
jt9com_.npts8=k/8;
|
||||
dataSink(k);
|
||||
if(n%10 == 1 or n == m_hsymStop) qApp->processEvents(); //Keep GUI responsive
|
||||
}
|
||||
@ -831,12 +831,16 @@ void MainWindow::on_DecodeButton_clicked() //Decode request
|
||||
|
||||
void MainWindow::freezeDecode(int n) //freezeDecode()
|
||||
{
|
||||
|
||||
decode();
|
||||
}
|
||||
|
||||
void MainWindow::decode() //decode()
|
||||
{
|
||||
m_len1=80;
|
||||
jt9com_.newdat=1;
|
||||
jt9com_.nagain=0;
|
||||
jt9com_.nfqso=g_pWideGraph->QSOfreq();
|
||||
m_tol=g_pWideGraph->Tol();
|
||||
jt9com_.ntol=m_tol;
|
||||
*future3 = QtConcurrent::run(decoder_, &m_TRperiod, &c0[0]);
|
||||
watcher3->setFuture(*future3);
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ private:
|
||||
qint32 m_nsps;
|
||||
qint32 m_hsymStop;
|
||||
qint32 m_len1;
|
||||
qint32 m_fQSO;
|
||||
|
||||
bool m_monitoring;
|
||||
bool m_transmitting;
|
||||
|
@ -66,7 +66,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string> UTC T dB DF</string>
|
||||
<string> UTC T dB Freq</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
|
@ -27,7 +27,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
||||
m_ScalePixmap = QPixmap(0,0);
|
||||
m_OverlayPixmap = QPixmap(0,0);
|
||||
m_Size = QSize(0,0);
|
||||
m_fQSO = 1050;
|
||||
m_fQSO = 1020;
|
||||
m_line = 0;
|
||||
m_fSample = 12000;
|
||||
m_nsps=6912;
|
||||
@ -296,7 +296,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
QPen pen0(Qt::green, 3); //Mark Cal Freq with green tick
|
||||
QPen pen0(Qt::green, 3); //Mark QSO Freq with green tick
|
||||
painter0.setPen(pen0);
|
||||
x = m_xClick;
|
||||
painter0.drawLine(x,15,x,30);
|
||||
@ -407,6 +407,7 @@ void CPlotter::setFQSO(int x, bool bf) //setFQSO()
|
||||
{
|
||||
if(bf) {
|
||||
m_fQSO=x; // x is freq in kHz
|
||||
m_xClick=XfromFreq(m_fQSO);
|
||||
} else {
|
||||
if(x<0) x=0; // x is pixel number
|
||||
if(x>m_Size.width()) x=m_Size.width();
|
||||
@ -564,7 +565,7 @@ double CPlotter::fGreen()
|
||||
void CPlotter::setNsps(int n) //setNSpan()
|
||||
{
|
||||
m_nsps=n;
|
||||
m_fftBinWidth=1500.0/1024.0;
|
||||
m_fftBinWidth=1500.0/2048.0;
|
||||
if(m_nsps==15360) m_fftBinWidth=1500.0/2048.0;
|
||||
if(m_nsps==40960) m_fftBinWidth=1500.0/6144.0;
|
||||
if(m_nsps==82944) m_fftBinWidth=1500.0/12288.0;
|
||||
|
@ -16,7 +16,7 @@ extern struct {
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int npts8; //npts in c0() array
|
||||
int nfb; //High decode limit (kHz)
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int kin;
|
||||
|
@ -183,6 +183,12 @@ void WideGraph::keyPressEvent(QKeyEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void WideGraph::setQSOfreq(int n)
|
||||
{
|
||||
m_qsoFreq=n;
|
||||
ui->widePlot->setFQSO(m_qsoFreq,true);
|
||||
}
|
||||
|
||||
int WideGraph::QSOfreq()
|
||||
{
|
||||
return ui->widePlot->fQSO();
|
||||
|
@ -18,6 +18,7 @@ public:
|
||||
|
||||
void dataSink2(float s[], float red[], float df3, int ihsym,
|
||||
int ndiskdata, uchar lstrong[]);
|
||||
void setQSOfreq(int n);
|
||||
int QSOfreq();
|
||||
int nSpan();
|
||||
int nStartFreq();
|
||||
|
Loading…
Reference in New Issue
Block a user