Working toward implementing JT9 decoder in WSJT-X.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@2663 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2012-10-15 17:43:49 +00:00
parent 3de7b86762
commit 884631a559
13 changed files with 148 additions and 103 deletions

42
jt9.txt
View File

@ -10,25 +10,25 @@ used for synchronization, so a transmission requires a total of 207/3
Exact symbol lengths are chosen so that nsps, the number of samples 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 per symbol (at 12000 samples per second) is a number with no prime
factor greater than 7. This choice makes for efficient FFTs. Tone factor greater than 7. This choice makes for efficient FFTs. Tone
spacing of the 9-FSK modulation is df=1/tsym=12000/nsps, the same as 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 keying rate. The total occupied bandwidth is 9*df.
Parameters of five JT9 sub-modes are summarized in the following Parameters of five JT9 sub-modes are summarized in the following
table, along with S/N thresholds measured by simulation on an AWGN table, along with S/N thresholds measured by simulation on an AWGN
channel. channel.
------------------------------------------------------------------------- --------------------------------------------------------------------------
Mode nsps nsps2 df tsym BW S/N* Tdec Tfree Factors Mode nsps nsps2 df tsym BW S/N* Tdec Tfree Factors
12000 1500 (Hz) (s) (Hz) (dB) (s) (s) of nsps 12000 1500 (Hz) (s) (Hz) (dB) (s) (s) of nsps nfft3
------------------------------------------------------------------------- --------------------------------------------------------------------------
JT9-1 6912 864 1.736 0.58 15.6 -26.9 52.5 7.5 2^8 3^3 JT9-1 6912 864 1.736 0.58 15.6 -26.9 52.5 7.5 2^8 3^3 1024
JT9-2 15360 1920 0.781 1.28 7.0 -30.2 112.3 7.7 2^10 3 5 JT9-2 15360 1920 0.781 1.28 7.0 -30.2 112.3 7.7 2^10 3 5 2048
JT9-5 40960 5120 0.293 3.41 2.6 -34.4 293.6 6.4 2^13 5 JT9-5 40960 5120 0.293 3.41 2.6 -34.4 293.6 6.4 2^13 5 6144
JT9-10 82944 10368 0.145 6.91 1.3 -37.5 591.0 9.0 2^10 3^4 JT9-10 82944 10368 0.145 6.91 1.3 -37.5 591.0 9.0 2^10 3^4 12288
JT9-30 252000 31500 0.048 21.00 0.4 -42.3 1788.5 11.5 2^5 3^2 5^3 7 JT9-30 252000 31500 0.048 21.00 0.4 -42.3 1788.5 11.5 2^5 3^2 5^3 7 32768
------------------------------------------------------------------------- --------------------------------------------------------------------------
* Noise power measured in a 2500 Hz bandwidth. * Noise power measured in a 2500 Hz bandwidth.
NB: nfft3 might be doubled and used with a sin^2 window.
Transmitting Transmitting
------------ ------------
@ -37,27 +37,27 @@ Transmitting
3. Interleave to scramble the bit order 3. Interleave to scramble the bit order
4. Assemble 3-bit groups to make (206+1)/3 = 69 symbols 4. Assemble 3-bit groups to make (206+1)/3 = 69 symbols
5. Gray-code the symbol values 5. Gray-code the symbol values
6. Insert 16 sync symbols ==> 69+15=81 channel symbols, values 0-8 6. Insert 16 sync symbols ==> 69+16=85 channel symbols, values 0-8
Receiving Receiving
--------- ---------
1. Apply noise blanking with the timf2 method 1. Apply noise blanking with the timf2 method
2. Filter to 1000 Hz bandwidth and downsample (1/8) to 1500 Hz, saving 2. Filter to 1000 Hz bandwidth and downsample (1/8) to 1500 Hz, saving
complex data to array c0(1350000). (use FIR? NFFT2/NFFT2A?) complex data to array c0(2,700,000).
3. Compute symbol-length spectra at half-symbol steps. Use for 3. Compute spectra at half-symbol steps. Use for waterfall display
waterfall display s(22000) and save in ss(184,22000) and s(22000) and save in ss(184,22000) and
savg(22000), for detecting sync vectors. savg(22000), for detecting sync vectors.
4. At time Tdec, find sync vectors in ss(); get estimates of DF, DT 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. 5. Do full-length FFT, NFFT1=96*nsps2, zero-padded as required.
6. For each candidate signal, do inverse FFT of length 1536. This 6. For each candidate signal, do inverse FFT of length 1536 (or 3072?).
yields 16 complex samples per symbol, and sync tone should be This yields 16 complex samples per symbol, and sync tone should be
close to zero frequency. close to zero frequency.
7. Use afc65b method to get improved values of DF, DT. 7. Use afc65b method to get improved values of DF, DT.
8. Tweak freq and time offset to 0. 8. Tweak freq and time offset to 0.
9. Compute 8-bin spectra of 69 data symbols: s2(8,69). Re-order bins 9. Compute 8-bin spectra of 69 data symbols: ssym(0:7,69). Re-order the
by removing Gray code. bins to remove Gray code.
10. Compute soft symbols for 206 bits. 10. Compute soft symbols for 206 bits (bit 207 is always 0).
11. Remove interleaving 11. Remove interleaving
12. Pack bits into bytes, send to Fano decoder 12. Pack bits into bytes, send to Fano decoder
13. If Fano succeeds, remove source encoding and display user message. 13. If Fano succeeds, remove source encoding and display user message.

View File

@ -11,7 +11,7 @@ program jt9
parameter (NSMAX=22000) !Max length of saved spectra parameter (NSMAX=22000) !Max length of saved spectra
integer*4 ihdr(11) integer*4 ihdr(11)
real*4 s(NSMAX) real*4 s(NSMAX)
real*4 ccfred(NSMAX) real*4 red(NSMAX)
logical*1 lstrong(0:1023) logical*1 lstrong(0:1023)
integer*1 i1SoftSymbols(207) integer*1 i1SoftSymbols(207)
character*22 msg character*22 msg
@ -83,7 +83,7 @@ program jt9
if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
! Emit signal readyForFFT ! Emit signal readyForFFT
call symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb, & call symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb, &
s,f0a,df3,ihsym,nzap,slimit,lstrong) s,red,f0a,df3,ihsym,nzap,slimit,lstrong)
nhsym0=nhsym nhsym0=nhsym
if(ihsym.ge.184) go to 10 if(ihsym.ge.184) go to 10
endif endif
@ -99,13 +99,13 @@ program jt9
nfqso=1500 nfqso=1500
! Get sync, approx freq ! Get sync, approx freq
call sync9(ss,tstep,f0a,df3,ntol,nfqso,sync,fpk,ccfred) call sync9(ss,tstep,f0a,df3,ntol,nfqso,sync,fpk,red)
fpk0=fpk fpk0=fpk
iz=1000.0/df3 iz=1000.0/df3
do i=1,iz do i=1,iz
freq=1000.0 + (i-1)*df3 freq=1000.0 + (i-1)*df3
write(72,3001) freq,ccfred(i) write(72,3001) freq,red(i),db(red(i))
3001 format(2f10.3) 3001 format(3f10.3)
enddo enddo
flush(72) flush(72)

44
lib/redsync.f90 Normal file
View File

@ -0,0 +1,44 @@
subroutine redsync(ss,ntrperiod,ihsym,iz,red)
Parameter (NSMAX=22000)
real*4 ss(184,NSMAX)
real*4 red(NSMAX)
integer ii(16) !Locations of sync half-symbols
data ii/1,11,21,31,41,51,61,77,89,101,113,125,137,149,161,169/
lagmax=9
if(ntrperiod.eq.2) lagmax=5
if(ntrperiod.eq.5) lagmax=2
if(ntrperiod.eq.10) lagmax=1
if(ntrperiod.eq.30) lagmax=1
do i=1,iz
smax=0.
do lag=-lagmax,lagmax
sig=0.
ns=0
ref=0.
nr=0
do j=1,16
k=ii(j)+lag
if(k.ge.1 .and. k.le.ihsym) then
sig=sig + ss(k,i)
ns=ns+1
endif
do n=k+2,k+8,2
if(n.ge.1 .and. n.le.ihsym) then
ref=ref + ss(n,i)
nr=nr+1
endif
enddo
enddo
s=0.
if(ref.gt.0.0) s=(sig/ns)/(ref/nr)
if(s.gt.smax) smax=s
enddo
red(i)=db(smax)
enddo
return
end subroutine redsync

View File

@ -1,5 +1,5 @@
subroutine symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb,s,f0a,df3, & subroutine symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb,s,red, &
ihsym,nzap,slimit,lstrong) f0a,df3,ihsym,nzap,slimit,lstrong)
! Input: ! Input:
! k pointer to the most recent new data ! k pointer to the most recent new data
@ -23,11 +23,11 @@ subroutine symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb,s,f0a,df3, &
parameter (NFFT1=1024) parameter (NFFT1=1024)
parameter (NFFT2=1024,NFFT2A=NFFT2/8) parameter (NFFT2=1024,NFFT2A=NFFT2/8)
parameter (MAXFFT3=32768) parameter (MAXFFT3=32768)
real*4 s(NSMAX),w(NFFT1),w3(MAXFFT3) real*4 s(NSMAX),w3(MAXFFT3)
real*4 x0(NFFT1),x1(NFFT1) real*4 x0(NFFT1),x1(NFFT1)
real*4 x2(NFFT1+105) real*4 x2(NFFT1+105)
real*4 xx(NMAX)
real*4 ssum(NSMAX) real*4 ssum(NSMAX)
real*4 red(NSMAX)
complex cx(0:MAXFFT3-1) complex cx(0:MAXFFT3-1)
logical*1 lstrong(0:1023) !Should be (0:512) logical*1 lstrong(0:1023) !Should be (0:512)
integer*2 id2 integer*2 id2
@ -73,7 +73,6 @@ subroutine symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb,s,f0a,df3, &
peaklimit=sigmas*max(10.0,rms) peaklimit=sigmas*max(10.0,rms)
faclim=3.0 faclim=3.0
px=0. px=0.
df2=12000.0/NFFT2
nwindow=2 nwindow=2
! nwindow=0 !### No windowing ### ! nwindow=0 !### No windowing ###
@ -137,20 +136,22 @@ subroutine symspec(k,ntrperiod,nsps,ndiskdat,nb,nbslider,pxdb,s,f0a,df3, &
999 continue 999 continue
call pctile(s,iz,50,xmed0) call pctile(s,iz,50,xmed0)
s(1:iz)=s(1:iz)/xmed0 s(1:iz)=s(1:iz)/xmed0
call pctile(ssum,iz,50,xmed1) call pctile(ssum,iz,50,xmed1)
savg(1:iz)=ssum(1:iz)/xmed1 savg(1:iz)=ssum(1:iz)/xmed1
! if(ihsym.eq.160) then call redsync(ss,ntrperiod,ihsym,iz,red)
! rewind 71
! do i=1,iz if(ihsym.eq.160) then
! write(71,3003) 1000+i*df3,savg(i) rewind 71
!3003 format(2f12.3) do i=1,iz
! enddo write(71,3003) 1000+i*df3,savg(i),red(i)
! flush(71) 3003 format(3f12.3)
! endif enddo
flush(71)
endif
return return
end subroutine symspec end subroutine symspec

View File

@ -4,7 +4,6 @@ subroutine sync9(ss,tstep,f0a,df3,ntol,nfqso,sync,fpk,ccfred)
real ss(184,NSMAX) real ss(184,NSMAX)
real ccfred(NSMAX) real ccfred(NSMAX)
integer ii0(16)
integer ii(16) !Locations of sync half-symbols integer ii(16) !Locations of sync half-symbols
data ii/1,11,21,31,41,51,61,77,89,101,113,125,137,149,161,169/ data ii/1,11,21,31,41,51,61,77,89,101,113,125,137,149,161,169/
integer isync(85) !Sync vector for half-symbols integer isync(85) !Sync vector for half-symbols

View File

@ -97,7 +97,7 @@ MainWindow::MainWindow(QWidget *parent) :
m_myGrid="FN20qi"; m_myGrid="FN20qi";
m_appDir = QApplication::applicationDirPath(); m_appDir = QApplication::applicationDirPath();
m_saveDir="/users/joe/wsjtx/install/save"; m_saveDir="/users/joe/wsjtx/install/save";
m_txFreq=125; m_txFreq=1500;
m_setftx=0; m_setftx=0;
m_loopall=false; m_loopall=false;
m_startAnother=false; m_startAnother=false;
@ -153,7 +153,7 @@ MainWindow::MainWindow(QWidget *parent) :
m_monitoring=true; // Start with Monitoring ON m_monitoring=true; // Start with Monitoring ON
soundInThread.setMonitoring(m_monitoring); soundInThread.setMonitoring(m_monitoring);
m_diskData=false; m_diskData=false;
m_tol=500; m_tol=50;
g_pWideGraph->setTol(m_tol); g_pWideGraph->setTol(m_tol);
// Create "m_worked", a dictionary of all calls in wsjt.log // Create "m_worked", a dictionary of all calls in wsjt.log
@ -301,7 +301,7 @@ void MainWindow::readSettings()
//-------------------------------------------------------------- dataSink() //-------------------------------------------------------------- dataSink()
void MainWindow::dataSink(int k) void MainWindow::dataSink(int k)
{ {
static float s[NSMAX],splot[NSMAX]; static float s[NSMAX],red[NSMAX],splot[NSMAX];
static int n=0; static int n=0;
static int ihsym=0; static int ihsym=0;
static int nzap=0; static int nzap=0;
@ -328,7 +328,7 @@ void MainWindow::dataSink(int k)
nb=0; nb=0;
if(m_NB) nb=1; if(m_NB) nb=1;
trmin=m_TRperiod/60; trmin=m_TRperiod/60;
symspec_(&k, &trmin, &m_nsps, &ndiskdat, &nb, &m_NBslider, &px, s, symspec_(&k, &trmin, &m_nsps, &ndiskdat, &nb, &m_NBslider, &px, s, red,
&f0a, &df3, &ihsym, &nzap, &slimit, lstrong); &f0a, &df3, &ihsym, &nzap, &slimit, lstrong);
if(ihsym <=0) return; if(ihsym <=0) return;
QString t; QString t;
@ -337,7 +337,7 @@ void MainWindow::dataSink(int k)
lab4->setText(t); lab4->setText(t);
ui->xThermo->setValue((double)px); //Update the thermometer ui->xThermo->setValue((double)px); //Update the thermometer
if(m_monitoring || m_diskData) { if(m_monitoring || m_diskData) {
g_pWideGraph->dataSink2(s,df3,ihsym,m_diskData,lstrong); g_pWideGraph->dataSink2(s,red,df3,ihsym,m_diskData,lstrong);
} }
//Average over specified number of spectra //Average over specified number of spectra
@ -594,7 +594,7 @@ void MainWindow::createStatusBar() //createStatusBar
void MainWindow::on_tolSpinBox_valueChanged(int i) //tolSpinBox void MainWindow::on_tolSpinBox_valueChanged(int i) //tolSpinBox
{ {
static int ntol[] = {10,20,50,100,200,500,1000}; static int ntol[] = {1,2,5,10,20,50,100,200,500,1000};
m_tol=ntol[i]; m_tol=ntol[i];
g_pWideGraph->setTol(m_tol); g_pWideGraph->setTol(m_tol);
ui->labTol1->setText(QString::number(ntol[i])); ui->labTol1->setText(QString::number(ntol[i]));
@ -753,12 +753,6 @@ void MainWindow::on_actionDelete_all_wav_files_in_SaveDir_triggered()
} }
} }
void MainWindow::on_actionFind_Delta_Phi_triggered() //Find dPhi
{
m_RxLog |= 8;
on_DecodeButton_clicked();
}
void MainWindow::on_actionF4_sets_Tx6_triggered() //F4 sets Tx6 void MainWindow::on_actionF4_sets_Tx6_triggered() //F4 sets Tx6
{ {
m_kb8rq = !m_kb8rq; m_kb8rq = !m_kb8rq;
@ -810,7 +804,7 @@ void MainWindow::on_actionAvailable_suffixes_and_add_on_prefixes_triggered()
void MainWindow::on_DecodeButton_clicked() //Decode request void MainWindow::on_DecodeButton_clicked() //Decode request
{ {
qDebug() << "A" << g_pWideGraph->QSOfreq() << m_tol;
} }
void MainWindow::freezeDecode(int n) //freezeDecode() void MainWindow::freezeDecode(int n) //freezeDecode()

View File

@ -65,7 +65,6 @@ private slots:
void on_actionOpen_next_in_directory_triggered(); void on_actionOpen_next_in_directory_triggered();
void on_actionDecode_remaining_files_in_directory_triggered(); void on_actionDecode_remaining_files_in_directory_triggered();
void on_actionDelete_all_wav_files_in_SaveDir_triggered(); void on_actionDelete_all_wav_files_in_SaveDir_triggered();
void on_actionFind_Delta_Phi_triggered();
void on_actionF4_sets_Tx6_triggered(); void on_actionF4_sets_Tx6_triggered();
void on_actionNo_shorthands_if_Tx1_triggered(); void on_actionNo_shorthands_if_Tx1_triggered();
void on_actionNo_Deep_Search_triggered(); void on_actionNo_Deep_Search_triggered();
@ -213,7 +212,7 @@ extern void getDev(int* numDevices,char hostAPI_DeviceName[][50],
extern "C" { extern "C" {
//----------------------------------------------------- C and Fortran routines //----------------------------------------------------- C and Fortran routines
void symspec_(int* k, int* ntrperiod, int* nsps, int* ndiskdat, void symspec_(int* k, int* ntrperiod, int* nsps, int* ndiskdat,
int* nb, int* m_NBslider, float* px, float s[], int* nb, int* m_NBslider, float* px, float s[], float red[],
float* f0a, float* df3, int* nhsym, int* nzap, float* f0a, float* df3, int* nhsym, int* nzap,
float* slimit, uchar lstrong[]); float* slimit, uchar lstrong[]);
void genjt9_(char* msg, int* minutes, char* msgsent, int itone[], void genjt9_(char* msg, int* minutes, char* msgsent, int itone[],

View File

@ -35,7 +35,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="centralWidget">
<widget class="QWidget" name=""> <widget class="QWidget" name="layoutWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>11</x> <x>11</x>
@ -627,7 +627,7 @@ p, li { white-space: pre-wrap; }
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>500</string> <string>50</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -661,7 +661,7 @@ p, li { white-space: pre-wrap; }
<number>0</number> <number>0</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>6</number> <number>9</number>
</property> </property>
<property name="value"> <property name="value">
<number>5</number> <number>5</number>

View File

@ -27,7 +27,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
m_ScalePixmap = QPixmap(0,0); m_ScalePixmap = QPixmap(0,0);
m_OverlayPixmap = QPixmap(0,0); m_OverlayPixmap = QPixmap(0,0);
m_Size = QSize(0,0); m_Size = QSize(0,0);
m_fQSO = 125; m_fQSO = 1050;
m_line = 0; m_line = 0;
m_fSample = 12000; m_fSample = 12000;
m_nsps=6912; m_nsps=6912;
@ -84,9 +84,9 @@ void CPlotter::paintEvent(QPaintEvent *) // paintEvent()
m_paintEventBusy=false; m_paintEventBusy=false;
} }
void CPlotter::draw(float swide[], int i0) //draw() void CPlotter::draw(float swide[], float red[], int i0) //draw()
{ {
int j; int j,y2;
float y; float y;
m_i0=i0; m_i0=i0;
@ -103,6 +103,8 @@ void CPlotter::draw(float swide[], int i0) //draw()
} }
painter2D.setPen(Qt::green); painter2D.setPen(Qt::green);
if(m_bJT9Sync) painter2D.setPen(Qt::red);
QPoint LineBuf[MAX_SCREENSIZE]; QPoint LineBuf[MAX_SCREENSIZE];
j=0; j=0;
bool strong0=false; bool strong0=false;
@ -124,8 +126,9 @@ void CPlotter::draw(float swide[], int i0) //draw()
m_hist1[y1]++; m_hist1[y1]++;
painter1.setPen(m_ColorTbl[y1]); painter1.setPen(m_ColorTbl[y1]);
painter1.drawPoint(i,0); painter1.drawPoint(i,0);
int y2 = gain*y + 30; if(m_bCurrent) y2 = gain*y + 30;
if(!m_bCurrent) y2=gain*10.0*log10(jt9com_.savg[i]); if(m_bCumulative) y2=gain*10.0*log10(jt9com_.savg[i]);
if(m_bJT9Sync) y2=3*gain*red[i];
if(strong != strong0 or i==m_w-1) { if(strong != strong0 or i==m_w-1) {
painter2D.drawPolyline(LineBuf,j); painter2D.drawPolyline(LineBuf,j);
j=0; j=0;
@ -297,19 +300,10 @@ void CPlotter::DrawOverlay() //DrawOverlay()
painter0.setPen(pen0); painter0.setPen(pen0);
x = m_xClick; x = m_xClick;
painter0.drawLine(x,15,x,30); painter0.drawLine(x,15,x,30);
int x0=(16384-m_i0)/m_binsPerPixel; int x1=x - m_tol/df;
m_fGreen=(x-x0)*df; int x2=x + m_tol/df;
x0 += (x0-x); pen0.setWidth(6);
QPen pen3(Qt::red, 3); painter0.drawLine(x1,28,x2,28);
painter0.setPen(pen3);
if(x0>0 and x0<w) painter0.drawLine(x0,15,x0,30);
// Now make the lower scale, using m_LowerScalePixmap and painter3
QRect rect1;
// QPainter painter3(&m_LowerScalePixmap);
// painter3.initFrom(this);
// painter3.setFont(Font);
// painter3.setPen(Qt::black);
df = 12000.0/m_nsps; df = 12000.0/m_nsps;
int nlabs=df*w/m_freqPerDiv + 1.0; int nlabs=df*w/m_freqPerDiv + 1.0;
@ -322,16 +316,6 @@ void CPlotter::DrawOverlay() //DrawOverlay()
if ((i%10) == 0) y=18; if ((i%10) == 0) y=18;
// painter3.drawLine(x,y,x,30); // painter3.drawLine(x,y,x,30);
} }
/*
//draw frequency values
MakeFrequencyStrs();
for( int i=0; i<=nlabs; i++) {
x = (int)( (float)i*pixperdiv - pixperdiv/2);
rect1.setRect(x,0, (int)pixperdiv, 20);
// painter3.drawText(rect1, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
}
*/
} }
void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs

View File

@ -27,6 +27,8 @@ public:
QSize sizeHint() const; QSize sizeHint() const;
QColor m_ColorTbl[256]; QColor m_ColorTbl[256];
bool m_bCurrent; bool m_bCurrent;
bool m_bCumulative;
bool m_bJT9Sync;
int m_plotZero; int m_plotZero;
int m_plotGain; int m_plotGain;
float m_fSpan; float m_fSpan;
@ -37,7 +39,7 @@ public:
qint32 m_tol; qint32 m_tol;
qint32 m_fCal; qint32 m_fCal;
void draw(float sw[], int i0); //Update the waterfalls void draw(float sw[], float red[], int i0); //Update the waterfall
void SetRunningState(bool running); void SetRunningState(bool running);
void setPlotZero(int plotZero); void setPlotZero(int plotZero);
int getPlotZero(); int getPlotZero();

View File

@ -41,8 +41,11 @@ WideGraph::WideGraph(QWidget *parent) :
m_dialFreq=settings.value("DialFreqMHz",473.000).toDouble(); m_dialFreq=settings.value("DialFreqMHz",473.000).toDouble();
ui->fDialLineEdit->setText(QString::number(m_dialFreq)); ui->fDialLineEdit->setText(QString::number(m_dialFreq));
ui->widePlot->m_bCurrent=settings.value("Current",true).toBool(); ui->widePlot->m_bCurrent=settings.value("Current",true).toBool();
ui->widePlot->m_bCumulative=settings.value("Cumulative",false).toBool();
ui->widePlot->m_bJT9Sync=settings.value("JT9Sync",false).toBool();
ui->rbCurrent->setChecked(ui->widePlot->m_bCurrent); ui->rbCurrent->setChecked(ui->widePlot->m_bCurrent);
ui->rbCumulative->setChecked(!ui->widePlot->m_bCurrent); ui->rbCumulative->setChecked(ui->widePlot->m_bCumulative);
ui->rbJT9Sync->setChecked(ui->widePlot->m_bJT9Sync);
int nbpp=settings.value("BinsPerPixel",1).toInt(); int nbpp=settings.value("BinsPerPixel",1).toInt();
ui->widePlot->setBinsPerPixel(nbpp); ui->widePlot->setBinsPerPixel(nbpp);
settings.endGroup(); settings.endGroup();
@ -70,12 +73,14 @@ void WideGraph::saveSettings()
settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value()); settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
settings.setValue("DialFreqMHz",m_dialFreq); settings.setValue("DialFreqMHz",m_dialFreq);
settings.setValue("Current",ui->widePlot->m_bCurrent); settings.setValue("Current",ui->widePlot->m_bCurrent);
settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
settings.setValue("JT9Sync",ui->widePlot->m_bJT9Sync);
settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel()); settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
settings.endGroup(); settings.endGroup();
} }
void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata, void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
uchar lstrong[]) int ndiskdata, uchar lstrong[])
{ {
static float splot[NSMAX]; static float splot[NSMAX];
static float swide[2048]; static float swide[2048];
@ -139,7 +144,7 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata,
} }
} }
ntr0=ntr; ntr0=ntr;
ui->widePlot->draw(swide,i0); ui->widePlot->draw(swide,red,i0);
} }
} }
@ -266,12 +271,23 @@ void WideGraph::setPeriod(int ntrperiod, int nsps)
ui->widePlot->setNsps(nsps); ui->widePlot->setNsps(nsps);
} }
void WideGraph::on_rbCurrent_toggled(bool checked) void WideGraph::on_rbCurrent_clicked()
{ {
ui->widePlot->m_bCurrent=checked; ui->widePlot->m_bCurrent=true;
ui->widePlot->m_bCumulative=false;
ui->widePlot->m_bJT9Sync=false;
} }
void WideGraph::on_rbCumulative_toggled(bool checked) void WideGraph::on_rbCumulative_clicked()
{ {
ui->widePlot->m_bCurrent=!checked; ui->widePlot->m_bCurrent=false;
ui->widePlot->m_bCumulative=true;
ui->widePlot->m_bJT9Sync=false;
}
void WideGraph::on_rbJT9Sync_clicked()
{
ui->widePlot->m_bCurrent=false;
ui->widePlot->m_bCumulative=false;
ui->widePlot->m_bJT9Sync=true;
} }

View File

@ -16,8 +16,8 @@ public:
double m_dialFreq; double m_dialFreq;
void dataSink2(float s[], float df3, int ihsym, int ndiskdata, void dataSink2(float s[], float red[], float df3, int ihsym,
uchar lstrong[]); int ndiskdata, uchar lstrong[]);
int QSOfreq(); int QSOfreq();
int nSpan(); int nSpan();
int nStartFreq(); int nStartFreq();
@ -53,10 +53,9 @@ private slots:
void on_gainSpinBox_valueChanged(int arg1); void on_gainSpinBox_valueChanged(int arg1);
void on_autoZeroPushButton_clicked(); void on_autoZeroPushButton_clicked();
void on_fDialLineEdit_editingFinished(); void on_fDialLineEdit_editingFinished();
void on_rbCurrent_clicked();
void on_rbCurrent_toggled(bool checked); void on_rbCumulative_clicked();
void on_rbJT9Sync_clicked();
void on_rbCumulative_toggled(bool checked);
private: private:
qint32 m_waterfallAvg; qint32 m_waterfallAvg;

View File

@ -297,6 +297,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QRadioButton" name="rbJT9Sync">
<property name="text">
<string>JT9 Sync</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_5"> <spacer name="horizontalSpacer_5">
<property name="orientation"> <property name="orientation">