mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 13:10:19 -04:00 
			
		
		
		
	Implement basic Rx capability for FT2 in WSJT-X.
This commit is contained in:
		
							parent
							
								
									c81af0bbe5
								
							
						
					
					
						commit
						5f03d97a9e
					
				| @ -509,6 +509,8 @@ set (wsjt_FSRCS | ||||
|   lib/mskrtd.f90 | ||||
|   lib/fsk4hf/ft2sim.f90 | ||||
|   lib/fsk4hf/ft2d.f90 | ||||
|   lib/ft2/cdatetime.f90 | ||||
|   lib/ft2/ft2_decode.f90 | ||||
|   lib/77bit/my_hash.f90 | ||||
|   lib/wsprd/osdwspr.f90 | ||||
|   lib/ft8/osd174_91.f90 | ||||
| @ -550,6 +552,7 @@ set (wsjt_FSRCS | ||||
|   lib/sync64.f90 | ||||
|   lib/sync65.f90 | ||||
|   lib/fsk4hf/getcandidates2.f90 | ||||
|   lib/ft2/getcandidates2a.f90 | ||||
|   lib/ft8/sync8.f90 | ||||
|   lib/ft8/sync8d.f90 | ||||
|   lib/sync9.f90 | ||||
|  | ||||
| @ -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 packjt77 | ||||
|   include 'ft2_params.f90' | ||||
|   character message*37,c77*77 | ||||
|   character*61 line | ||||
|   character*37 decodes(100) | ||||
|   character*120 data_dir | ||||
|   character*17 cdatetime | ||||
|   character*6 mycall,hiscall | ||||
|   character*17 cdatetime0,cdatetime,cdt | ||||
|   character*6 mycall,hiscall,hhmmss | ||||
|   complex c2(0:NMAX/16-1)                  !Complex waveform | ||||
|   complex cb(0:NMAX/16-1) | ||||
|   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 | ||||
|   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 | ||||
|   dt=1/fs                                !Sample interval after downsample (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 | ||||
|   maxcand=100 | ||||
|   nfqso=-1 | ||||
|   call getcandidates2(iwave,fa,fb,maxcand,savg,candidate,ncand) | ||||
|   call getcandidates2a(iwave,fa,fb,maxcand,savg,candidate,ncand) | ||||
|   ndecodes=0 | ||||
|   do icand=1,ncand | ||||
|      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 ### | ||||
|            nsnr=nint(xsnr) | ||||
|            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 | ||||
|            write(12,1000) cdatetime,nsnr,ibest/750.0,nint(freq),message,    & | ||||
|                 nseq,nharderror,nhardmin | ||||
| 1000       format(a17,i4,f6.2,i5,' Rx  ',a37,3i5) | ||||
|            if(hhmmss.eq.'      ') write(*,1002) cdatetime0,nsnr,             & | ||||
|                 ibest/750.0,nint(freq),message,nseq,nharderror,nhardmin | ||||
| 1002       format(a17,i4,f6.2,i5,' Rx  ',a37,3i5) | ||||
|            close(24) | ||||
| 
 | ||||
| !### Temporary: assume most recent decoded message conveys "hiscall". | ||||
|            i0=index(message,' ') | ||||
| @ -290,4 +301,3 @@ subroutine ft2_downsample(iwave,f0,c) | ||||
|   c=c1(0:NMAX/16-1) | ||||
|   return | ||||
| end subroutine ft2_downsample | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
| @ -61,4 +61,4 @@ subroutine getcandidates2(id,fa,fb,maxcand,savg,candidate,ncand) | ||||
|   endif | ||||
| 
 | ||||
|   return | ||||
| end subroutine getcandidates2 | ||||
| end subroutine getcandidates2a | ||||
| @ -23,7 +23,8 @@ namespace | ||||
|     "MSK144", | ||||
|     "QRA64", | ||||
|     "FreqCal", | ||||
|     "FT8" | ||||
|     "FT8", | ||||
|     "FT2" | ||||
|   }; | ||||
|   std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]); | ||||
| } | ||||
|  | ||||
| @ -49,6 +49,7 @@ public: | ||||
|     QRA64, | ||||
|     FreqCal, | ||||
|     FT8, | ||||
|     FT2, | ||||
|     MODES_END_SENTINAL_AND_COUNT // this must be last
 | ||||
|   }; | ||||
|   Q_ENUM (Mode) | ||||
|  | ||||
| @ -159,6 +159,10 @@ extern "C" { | ||||
|   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 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
 | ||||
| @ -544,6 +548,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, | ||||
|   on_EraseButton_clicked (); | ||||
| 
 | ||||
|   QActionGroup* modeGroup = new QActionGroup(this); | ||||
|   ui->actionFT2->setActionGroup(modeGroup); | ||||
|   ui->actionFT8->setActionGroup(modeGroup); | ||||
|   ui->actionJT9->setActionGroup(modeGroup); | ||||
|   ui->actionJT65->setActionGroup(modeGroup); | ||||
| @ -874,6 +879,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, | ||||
|   if(m_bFast9) m_bFastMode=true; | ||||
|   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=="JT4") on_actionJT4_triggered(); | ||||
|   if(m_mode=="JT9") on_actionJT9_triggered(); | ||||
| @ -1345,7 +1351,8 @@ void MainWindow::dataSink(qint64 frames) | ||||
|   if(m_monitoring || 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(); | ||||
|   if (m_mode == "FreqCal" | ||||
| @ -1546,7 +1553,6 @@ void MainWindow::fastSink(qint64 frames) | ||||
| { | ||||
|   int k (frames); | ||||
|   bool decodeNow=false; | ||||
| 
 | ||||
|   if(k < m_k0) {                                 //New sequence ?
 | ||||
|     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[]
 | ||||
| @ -3836,6 +3842,7 @@ void MainWindow::guiUpdate() | ||||
| 
 | ||||
| //Once per second:
 | ||||
|   if(nsec != m_sec0) { | ||||
| //    qDebug() << "cc oneSec" << dec_data.params.kin << m_ihsym;
 | ||||
|     // 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();
 | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
|   m_mode="FT8"; | ||||
| @ -5599,8 +5652,6 @@ void MainWindow::on_actionFT8_triggered() | ||||
|   statusChanged(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void MainWindow::on_actionJT4_triggered() | ||||
| { | ||||
|   m_mode="JT4"; | ||||
| @ -8499,3 +8550,41 @@ void MainWindow::write_all(QString txRx, QString message) | ||||
|       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; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -49,6 +49,7 @@ | ||||
| #define NUM_CW_SYMBOLS 250 | ||||
| #define TX_SAMPLE_RATE 48000 | ||||
| #define N_WIDGETS 33 | ||||
| #define NRING 432000 | ||||
| 
 | ||||
| extern int volatile itone[NUM_ISCAT_SYMBOLS];   //Audio tones for all Tx symbols
 | ||||
| extern int volatile icw[NUM_CW_SYMBOLS];	    //Dits for CW ID
 | ||||
| @ -200,6 +201,7 @@ private slots: | ||||
|   void on_actionJT65_triggered(); | ||||
|   void on_actionJT9_JT65_triggered(); | ||||
|   void on_actionJT4_triggered(); | ||||
|   void on_actionFT2_triggered(); | ||||
|   void on_actionFT8_triggered(); | ||||
|   void on_TxFreqSpinBox_valueChanged(int arg1); | ||||
|   void on_actionSave_decoded_triggered(); | ||||
| @ -309,6 +311,7 @@ private slots: | ||||
|   void on_comboBoxHoundSort_activated (int index); | ||||
|   void not_GA_warning_message (); | ||||
|   void checkMSK144ContestType(); | ||||
|   void ft2Data(int k); | ||||
|   int  setTxMsg(int n); | ||||
|   bool stdCall(QString const& w); | ||||
| 
 | ||||
|  | ||||
| @ -2705,6 +2705,7 @@ list. The list can be maintained in Settings (F2).</string> | ||||
|     <property name="title"> | ||||
|      <string>Mode</string> | ||||
|     </property> | ||||
|     <addaction name="actionFT2"/> | ||||
|     <addaction name="actionFT8"/> | ||||
|     <addaction name="actionJT4"/> | ||||
|     <addaction name="actionJT9"/> | ||||
| @ -3338,6 +3339,14 @@ list. The list can be maintained in Settings (F2).</string> | ||||
|     <string>Erase WSPR hashtable</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionFT2"> | ||||
|    <property name="checkable"> | ||||
|     <bool>true</bool> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>FT2</string> | ||||
|    </property> | ||||
|   </action> | ||||
|  </widget> | ||||
|  <layoutdefault spacing="6" margin="11"/> | ||||
|  <customwidgets> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user