Implement basic Rx capability for FT2 in WSJT-X.

This commit is contained in:
Joe Taylor 2019-01-18 11:51:15 -05:00
parent c81af0bbe5
commit 5f03d97a9e
8 changed files with 132 additions and 16 deletions

View File

@ -509,6 +509,8 @@ set (wsjt_FSRCS
lib/mskrtd.f90 lib/mskrtd.f90
lib/fsk4hf/ft2sim.f90 lib/fsk4hf/ft2sim.f90
lib/fsk4hf/ft2d.f90 lib/fsk4hf/ft2d.f90
lib/ft2/cdatetime.f90
lib/ft2/ft2_decode.f90
lib/77bit/my_hash.f90 lib/77bit/my_hash.f90
lib/wsprd/osdwspr.f90 lib/wsprd/osdwspr.f90
lib/ft8/osd174_91.f90 lib/ft8/osd174_91.f90
@ -550,6 +552,7 @@ set (wsjt_FSRCS
lib/sync64.f90 lib/sync64.f90
lib/sync65.f90 lib/sync65.f90
lib/fsk4hf/getcandidates2.f90 lib/fsk4hf/getcandidates2.f90
lib/ft2/getcandidates2a.f90
lib/ft8/sync8.f90 lib/ft8/sync8.f90
lib/ft8/sync8d.f90 lib/ft8/sync8d.f90
lib/sync9.f90 lib/sync9.f90

View File

@ -1,13 +1,14 @@
subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes,mycall,hiscall,nrx) subroutine ft2_decode(cdatetime0,nfqso,iwave,ndecodes,mycall,hiscall,nrx,line)
use crc use crc
use packjt77 use packjt77
include 'ft2_params.f90' include 'ft2_params.f90'
character message*37,c77*77 character message*37,c77*77
character*61 line
character*37 decodes(100) character*37 decodes(100)
character*120 data_dir character*120 data_dir
character*17 cdatetime character*17 cdatetime0,cdatetime,cdt
character*6 mycall,hiscall character*6 mycall,hiscall,hhmmss
complex c2(0:NMAX/16-1) !Complex waveform complex c2(0:NMAX/16-1) !Complex waveform
complex cb(0:NMAX/16-1) complex cb(0:NMAX/16-1)
complex cd(0:144*10-1) !Complex waveform complex cd(0:144*10-1) !Complex waveform
@ -30,6 +31,12 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes,mycall,hiscall,nrx)
logical unpk77_success logical unpk77_success
data s16/0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0/ data s16/0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0/
hhmmss=' '
if(cdatetime0==' ') then
cdt=cdatetime()
hhmmss=cdt(8:13)
endif
fs=12000.0/NDOWN !Sample rate fs=12000.0/NDOWN !Sample rate
dt=1/fs !Sample interval after downsample (s) dt=1/fs !Sample interval after downsample (s)
tt=NSPS*dt !Duration of "itone" symbols (s) tt=NSPS*dt !Duration of "itone" symbols (s)
@ -63,7 +70,7 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes,mycall,hiscall,nrx)
syncmin=0.2 syncmin=0.2
maxcand=100 maxcand=100
nfqso=-1 nfqso=-1
call getcandidates2(iwave,fa,fb,maxcand,savg,candidate,ncand) call getcandidates2a(iwave,fa,fb,maxcand,savg,candidate,ncand)
ndecodes=0 ndecodes=0
do icand=1,ncand do icand=1,ncand
f0=candidate(1,icand) f0=candidate(1,icand)
@ -191,11 +198,15 @@ subroutine ft2_decode(cdatetime,nfqso,iwave,ndecodes,mycall,hiscall,nrx)
xsnr=db(sybest*sybest) - 115.0 !### Rough estimate of S/N ### xsnr=db(sybest*sybest) - 115.0 !### Rough estimate of S/N ###
nsnr=nint(xsnr) nsnr=nint(xsnr)
freq=f0+dfbest freq=f0+dfbest
write(*,1000) cdatetime,nsnr,ibest/750.0,nint(freq),message, & write(line,1000) hhmmss,nsnr,ibest/750.0,nint(freq),message
1000 format(a6,i4,f5.2,i5,' + ',1x,a37)
open(24,file='all_ft2.txt',status='unknown',position='append')
write(24,1002) cdatetime0,nsnr,ibest/750.0,nint(freq),message, &
nseq,nharderror,nhardmin nseq,nharderror,nhardmin
write(12,1000) cdatetime,nsnr,ibest/750.0,nint(freq),message, & if(hhmmss.eq.' ') write(*,1002) cdatetime0,nsnr, &
nseq,nharderror,nhardmin ibest/750.0,nint(freq),message,nseq,nharderror,nhardmin
1000 format(a17,i4,f6.2,i5,' Rx ',a37,3i5) 1002 format(a17,i4,f6.2,i5,' Rx ',a37,3i5)
close(24)
!### Temporary: assume most recent decoded message conveys "hiscall". !### Temporary: assume most recent decoded message conveys "hiscall".
i0=index(message,' ') i0=index(message,' ')
@ -290,4 +301,3 @@ subroutine ft2_downsample(iwave,f0,c)
c=c1(0:NMAX/16-1) c=c1(0:NMAX/16-1)
return return
end subroutine ft2_downsample end subroutine ft2_downsample

View File

@ -1,4 +1,4 @@
subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand) subroutine getcandidates2a(id,fa,fb,maxcand,savg,candidate,ncand)
! For now, hardwired to find the largest peak in the average spectrum ! For now, hardwired to find the largest peak in the average spectrum
@ -61,4 +61,4 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand)
endif endif
return return
end subroutine getcandidates2 end subroutine getcandidates2a

View File

@ -23,7 +23,8 @@ namespace
"MSK144", "MSK144",
"QRA64", "QRA64",
"FreqCal", "FreqCal",
"FT8" "FT8",
"FT2"
}; };
std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]); std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]);
} }

View File

@ -49,6 +49,7 @@ public:
QRA64, QRA64,
FreqCal, FreqCal,
FT8, FT8,
FT2,
MODES_END_SENTINAL_AND_COUNT // this must be last MODES_END_SENTINAL_AND_COUNT // this must be last
}; };
Q_ENUM (Mode) Q_ENUM (Mode)

View File

@ -159,6 +159,10 @@ extern "C" {
void plotsave_(float swide[], int* m_w , int* m_h1, int* irow); void plotsave_(float swide[], int* m_w , int* m_h1, int* irow);
void chkcall_(char* w, char* basc_call, bool cok, int len1, int len2); void chkcall_(char* w, char* basc_call, bool cok, int len1, int len2);
void ft2_decode_(char* cdatetime, int* nfqso, short int id[], int* ndecodes,
char* mycall6, char* hiscall6, int* nrx, char* line,
int len1, int len2, int len3, int len4);
} }
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
@ -544,6 +548,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
on_EraseButton_clicked (); on_EraseButton_clicked ();
QActionGroup* modeGroup = new QActionGroup(this); QActionGroup* modeGroup = new QActionGroup(this);
ui->actionFT2->setActionGroup(modeGroup);
ui->actionFT8->setActionGroup(modeGroup); ui->actionFT8->setActionGroup(modeGroup);
ui->actionJT9->setActionGroup(modeGroup); ui->actionJT9->setActionGroup(modeGroup);
ui->actionJT65->setActionGroup(modeGroup); ui->actionJT65->setActionGroup(modeGroup);
@ -874,6 +879,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
if(m_bFast9) m_bFastMode=true; if(m_bFast9) m_bFastMode=true;
ui->cbFast9->setChecked(m_bFast9 or m_bFastMode); ui->cbFast9->setChecked(m_bFast9 or m_bFastMode);
if(m_mode=="FT2") on_actionFT2_triggered();
if(m_mode=="FT8") on_actionFT8_triggered(); if(m_mode=="FT8") on_actionFT8_triggered();
if(m_mode=="JT4") on_actionJT4_triggered(); if(m_mode=="JT4") on_actionJT4_triggered();
if(m_mode=="JT9") on_actionJT9_triggered(); if(m_mode=="JT9") on_actionJT9_triggered();
@ -1345,7 +1351,8 @@ void MainWindow::dataSink(qint64 frames)
if(m_monitoring || m_diskData) { if(m_monitoring || m_diskData) {
m_wideGraph->dataSink2(s,m_df3,m_ihsym,m_diskData); m_wideGraph->dataSink2(s,m_df3,m_ihsym,m_diskData);
} }
if(m_mode=="MSK144") return; if(m_mode=="FT2") ft2Data(k);
if(m_mode=="MSK144" or m_mode=="FT2") return;
fixStop(); fixStop();
if (m_mode == "FreqCal" if (m_mode == "FreqCal"
@ -1546,7 +1553,6 @@ void MainWindow::fastSink(qint64 frames)
{ {
int k (frames); int k (frames);
bool decodeNow=false; bool decodeNow=false;
if(k < m_k0) { //New sequence ? if(k < m_k0) { //New sequence ?
memcpy(fast_green2,fast_green,4*703); //Copy fast_green[] to fast_green2[] memcpy(fast_green2,fast_green,4*703); //Copy fast_green[] to fast_green2[]
memcpy(fast_s2,fast_s,4*703*64); //Copy fast_s[] into fast_s2[] memcpy(fast_s2,fast_s,4*703*64); //Copy fast_s[] into fast_s2[]
@ -3836,6 +3842,7 @@ void MainWindow::guiUpdate()
//Once per second: //Once per second:
if(nsec != m_sec0) { if(nsec != m_sec0) {
// qDebug() << "cc oneSec" << dec_data.params.kin << m_ihsym;
// if((!m_msgAvgWidget or (m_msgAvgWidget and !m_msgAvgWidget->isVisible())) // if((!m_msgAvgWidget or (m_msgAvgWidget and !m_msgAvgWidget->isVisible()))
// and (SpecOp::NONE < m_config.special_op_id()) and (SpecOp::HOUND > m_config.special_op_id())) on_actionFox_Log_triggered(); // and (SpecOp::NONE < m_config.special_op_id()) and (SpecOp::HOUND > m_config.special_op_id())) on_actionFox_Log_triggered();
if(m_freqNominal!=0 and m_freqNominal<50000000 and m_config.enable_VHF_features()) { if(m_freqNominal!=0 and m_freqNominal<50000000 and m_config.enable_VHF_features()) {
@ -5497,6 +5504,52 @@ void MainWindow::displayWidgets(qint64 n)
genStdMsgs (m_rpt, true); genStdMsgs (m_rpt, true);
} }
void MainWindow::on_actionFT2_triggered()
{
m_mode="FT2";
m_modeTx="FT2";
m_TRperiod=2147483647;
bool bVHF=m_config.enable_VHF_features();
m_bFast9=false;
m_bFastMode=false;
WSPR_config(false);
switch_mode (Modes::FT2);
m_nsps=6912;
m_FFTSize = m_nsps/2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=50;
setup_status_bar (bVHF);
m_toneSpacing=0.0; //???
ui->actionFT2->setChecked(true); //???
m_wideGraph->setMode(m_mode);
m_wideGraph->setModeTx(m_modeTx);
VHF_features_enabled(bVHF);
ui->cbAutoSeq->setChecked(false);
m_fastGraph->hide();
m_wideGraph->show();
ui->decodedTextLabel2->setText(" UTC dB DT Freq Message");
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
ui->label_7->setText("Rx Frequency");
ui->label_6->setText("Band Activity");
ui->decodedTextLabel->setText( " UTC dB DT Freq Message");
displayWidgets(nWidgets("111010000100111000010000100110001"));
ui->txrb2->setEnabled(true);
ui->txrb4->setEnabled(true);
ui->txrb5->setEnabled(true);
ui->txrb6->setEnabled(true);
ui->txb2->setEnabled(true);
ui->txb4->setEnabled(true);
ui->txb5->setEnabled(true);
ui->txb6->setEnabled(true);
ui->txFirstCheckBox->setEnabled(true);
ui->cbAutoSeq->setEnabled(true);
ui->labDXped->setVisible(false);
ui->labDXped->setText("");
statusChanged();
}
void MainWindow::on_actionFT8_triggered() void MainWindow::on_actionFT8_triggered()
{ {
m_mode="FT8"; m_mode="FT8";
@ -5599,8 +5652,6 @@ void MainWindow::on_actionFT8_triggered()
statusChanged(); statusChanged();
} }
void MainWindow::on_actionJT4_triggered() void MainWindow::on_actionJT4_triggered()
{ {
m_mode="JT4"; m_mode="JT4";
@ -8499,3 +8550,41 @@ void MainWindow::write_all(QString txRx, QString message)
MessageBox::warning_message(this, tr ("Log File Error"), message2); }); MessageBox::warning_message(this, tr ("Log File Error"), message2); });
} }
} }
void MainWindow::ft2Data(int k)
{
static int nhsec0=-1;
short id[30000];
int nhsec=k/6000;
if(nhsec!=nhsec0) {
//Process FT2 data at 0.5 s intervals
int j=k-30000;
if(j<0) j+=NRING;
for(int i=0; i<30000; i++) {
id[i]=dec_data.d2[j];
j++;
if(j>=NRING) j=j-NRING;
}
if(k>=NRING) {
k=k-NRING;
dec_data.params.kin=k;
}
char cdatetime[]=" ";
char mycall6[] ="K1JT ";
char hiscall6[]="K9AN ";
char line[61];
int nfqso=1500;
int ndecodes=0;
int nrx=-1;
ft2_decode_(cdatetime,&nfqso,id,&ndecodes,mycall6,hiscall6,&nrx,&line[0],
17,6,6,61);
line[60]=0;
if(ndecodes>0) {
QString sline{QString::fromLatin1(line)};
DecodedText decodedtext {sline.replace(QChar::LineFeed,"")};
ui->decodedTextBrowser->displayDecodedText (decodedtext,m_baseCall,m_mode,
m_config.DXCC(),m_logBook,m_currentBand,m_config.ppfx());
}
nhsec0=nhsec;
}
}

View File

@ -49,6 +49,7 @@
#define NUM_CW_SYMBOLS 250 #define NUM_CW_SYMBOLS 250
#define TX_SAMPLE_RATE 48000 #define TX_SAMPLE_RATE 48000
#define N_WIDGETS 33 #define N_WIDGETS 33
#define NRING 432000
extern int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols extern int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
extern int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID extern int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID
@ -200,6 +201,7 @@ private slots:
void on_actionJT65_triggered(); void on_actionJT65_triggered();
void on_actionJT9_JT65_triggered(); void on_actionJT9_JT65_triggered();
void on_actionJT4_triggered(); void on_actionJT4_triggered();
void on_actionFT2_triggered();
void on_actionFT8_triggered(); void on_actionFT8_triggered();
void on_TxFreqSpinBox_valueChanged(int arg1); void on_TxFreqSpinBox_valueChanged(int arg1);
void on_actionSave_decoded_triggered(); void on_actionSave_decoded_triggered();
@ -309,6 +311,7 @@ private slots:
void on_comboBoxHoundSort_activated (int index); void on_comboBoxHoundSort_activated (int index);
void not_GA_warning_message (); void not_GA_warning_message ();
void checkMSK144ContestType(); void checkMSK144ContestType();
void ft2Data(int k);
int setTxMsg(int n); int setTxMsg(int n);
bool stdCall(QString const& w); bool stdCall(QString const& w);

View File

@ -2705,6 +2705,7 @@ list. The list can be maintained in Settings (F2).</string>
<property name="title"> <property name="title">
<string>Mode</string> <string>Mode</string>
</property> </property>
<addaction name="actionFT2"/>
<addaction name="actionFT8"/> <addaction name="actionFT8"/>
<addaction name="actionJT4"/> <addaction name="actionJT4"/>
<addaction name="actionJT9"/> <addaction name="actionJT9"/>
@ -3338,6 +3339,14 @@ list. The list can be maintained in Settings (F2).</string>
<string>Erase WSPR hashtable</string> <string>Erase WSPR hashtable</string>
</property> </property>
</action> </action>
<action name="actionFT2">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>FT2</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>