Fixed issue with duplicate decodes based on the ring buffer after tx cycles completed when it lined up with a decode cycle.
This commit is contained in:
		
							parent
							
								
									f4ae642cec
								
							
						
					
					
						commit
						720bd6b22a
					
				| @ -48,7 +48,11 @@ void Detector::clear () | |||||||
|   qint64 now (DriftingDateTime::currentMSecsSinceEpoch ()); |   qint64 now (DriftingDateTime::currentMSecsSinceEpoch ()); | ||||||
|   unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000)); |   unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000)); | ||||||
|   dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0]))); |   dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0]))); | ||||||
|   m_bufferPos = 0; |   m_bufferPos = m_samplesPerFFT; | ||||||
|  | 
 | ||||||
|  |   // erase everything after kin.
 | ||||||
|  |   memset(dec_data.d2 + dec_data.params.kin, 0, sizeof(dec_data.d2) - (sizeof(dec_data.d2[0]) * dec_data.params.kin)); | ||||||
|  | 
 | ||||||
|   qDebug() << "advancing detector buffer to" << dec_data.params.kin; |   qDebug() << "advancing detector buffer to" << dec_data.params.kin; | ||||||
| #else | #else | ||||||
|   dec_data.params.kin = 0; |   dec_data.params.kin = 0; | ||||||
|  | |||||||
| @ -7,9 +7,8 @@ | |||||||
| #define RX_SAMPLE_RATE 12000 | #define RX_SAMPLE_RATE 12000 | ||||||
| 
 | 
 | ||||||
| #define JS8_USE_REFSPEC    1       // compute the signal refspec
 | #define JS8_USE_REFSPEC    1       // compute the signal refspec
 | ||||||
| #define JS8_USE_IHSYM      1       // compute ihsym manually instead of from symspec
 | #define JS8_USE_IHSYM      0       // compute ihsym manually instead of from symspec
 | ||||||
| #define JS8_RING_BUFFER    1       // use a ring buffer instead of clearing the decode frames
 | #define JS8_RING_BUFFER    1       // use a ring buffer instead of clearing the decode frames
 | ||||||
| #define JS8_DECODER_ONE    1       // decode only one mode at a time
 |  | ||||||
| #define JS8_DECODER_E2S    0       // decode every 2 seconds instead of at the half symbol stop
 | #define JS8_DECODER_E2S    0       // decode every 2 seconds instead of at the half symbol stop
 | ||||||
| 
 | 
 | ||||||
| #define JS8_NUM_SYMBOLS    79 | #define JS8_NUM_SYMBOLS    79 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								lib/jt9.f90
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lib/jt9.f90
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | |||||||
| program jt9 | program jt9 | ||||||
| 
 | 
 | ||||||
| ! Decoder for JT9.  Can run stand-alone, reading data from *.wav files; | ! Decoder for js8.  Can run stand-alone, reading data from *.wav files; | ||||||
| ! or as the back end of wsjt-x, with data placed in a shared memory region. | ! or as the back end of js8call, with data placed in a shared memory region. | ||||||
| 
 | 
 | ||||||
|   use options |   use options | ||||||
|   use prog_args |   use prog_args | ||||||
| @ -15,7 +15,6 @@ program jt9 | |||||||
| 
 | 
 | ||||||
|   integer(C_INT) iret |   integer(C_INT) iret | ||||||
|   type(wav_header) wav |   type(wav_header) wav | ||||||
|   real*4 s(NSMAX) |  | ||||||
|   character c |   character c | ||||||
|   character(len=500) optarg, infile |   character(len=500) optarg, infile | ||||||
|   character wisfile*80 |   character wisfile*80 | ||||||
| @ -234,15 +233,6 @@ program jt9 | |||||||
| 4       call timer('read_wav',1) | 4       call timer('read_wav',1) | ||||||
|         nhsym=(k-2048)/kstep |         nhsym=(k-2048)/kstep | ||||||
|         if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then |         if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then | ||||||
|            if(mode.eq.9 .or. mode.eq.74) then |  | ||||||
| ! Compute rough symbol spectra for the JT9 decoder |  | ||||||
|               ingain=0 |  | ||||||
|               call timer('symspec ',0) |  | ||||||
|               nminw=1 |  | ||||||
|               call symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,  & |  | ||||||
|                    s,df3,ihsym,npts8,pxdbmax) |  | ||||||
|               call timer('symspec ',1) |  | ||||||
|            endif |  | ||||||
|            nhsym0=nhsym |            nhsym0=nhsym | ||||||
|            if(nhsym.ge.181) exit |            if(nhsym.ge.181) exit | ||||||
|         endif |         endif | ||||||
|  | |||||||
| @ -1,9 +1,10 @@ | |||||||
| subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,s,   & | subroutine symspec(shared_data,k,k0,ntrperiod,nsps,ingain,nminw,pxdb,s,   & | ||||||
|      df3,ihsym,npts8,pxdbmax) |      df3,ihsym,npts8,pxdbmax) | ||||||
| 
 | 
 | ||||||
| ! Input: | ! Input: | ||||||
| !  shared_data  pointer to the most recent new data | !  shared_data  pointer to the most recent new data | ||||||
| !  k            frames in that data | !  k            frames in that data | ||||||
|  | !  k0           the last k observed | ||||||
| !  ntrperiod    T/R sequence length, minutes | !  ntrperiod    T/R sequence length, minutes | ||||||
| !  nsps         samples per symbol, at 12000 Hz | !  nsps         samples per symbol, at 12000 Hz | ||||||
| !  ndiskdat     0/1 to indicate if data from disk | !  ndiskdat     0/1 to indicate if data from disk | ||||||
| @ -32,7 +33,7 @@ subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,s,   & | |||||||
|   integer nch(7) |   integer nch(7) | ||||||
| 
 | 
 | ||||||
|   common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456) |   common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456) | ||||||
|   data k0/99999999/,nfft3z/0/ |   data nfft3z/0/ | ||||||
|   data nch/1,2,4,9,18,36,72/ |   data nch/1,2,4,9,18,36,72/ | ||||||
|   equivalence (xc,cx) |   equivalence (xc,cx) | ||||||
|   save |   save | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ | |||||||
| 
 | 
 | ||||||
| extern "C" { | extern "C" { | ||||||
|   //----------------------------------------------------- C and Fortran routines
 |   //----------------------------------------------------- C and Fortran routines
 | ||||||
|   void symspec_(struct dec_data *, int* k, int* ntrperiod, int* nsps, int* ingain, |   void symspec_(struct dec_data *, int* k, int* k0, int* ntrperiod, int* nsps, int* ingain, | ||||||
|                 int* minw, float* px, float s[], float* df3, int* nhsym, int* npts8, |                 int* minw, float* px, float s[], float* df3, int* nhsym, int* npts8, | ||||||
|                 float *m_pxmax); |                 float *m_pxmax); | ||||||
| 
 | 
 | ||||||
| @ -2542,11 +2542,16 @@ int MainWindow::computeFramesNeededForDecode(int submode, int period){ | |||||||
| //-------------------------------------------------------------- dataSink()
 | //-------------------------------------------------------------- dataSink()
 | ||||||
| void MainWindow::dataSink(qint64 frames) | void MainWindow::dataSink(qint64 frames) | ||||||
| { | { | ||||||
|     static int k0 = 0; |     static int k0 = 999999999; | ||||||
|     static float s[NSMAX]; |     static float s[NSMAX]; | ||||||
|     char line[80]; |     char line[80]; | ||||||
| 
 | 
 | ||||||
|     int k (frames); |     int k (frames); | ||||||
|  |     if(k0 == 999999999){ | ||||||
|  |         m_ihsym = int((float)frames/(float)m_nsps)*2; | ||||||
|  |         k0 = k; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     QString fname {QDir::toNativeSeparators(m_config.writeable_data_dir ().absoluteFilePath ("refspec.dat"))}; |     QString fname {QDir::toNativeSeparators(m_config.writeable_data_dir ().absoluteFilePath ("refspec.dat"))}; | ||||||
|     QByteArray bafname = fname.toLatin1(); |     QByteArray bafname = fname.toLatin1(); | ||||||
|     const char *c_fname = bafname.data(); |     const char *c_fname = bafname.data(); | ||||||
| @ -2588,25 +2593,37 @@ void MainWindow::dataSink(qint64 frames) | |||||||
|     } |     } | ||||||
|     k0 = k; |     k0 = k; | ||||||
|     int ihs = m_ihsym; |     int ihs = m_ihsym; | ||||||
|     symspec_(&dec_data,&k,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&ihs,&m_npts8,&m_pxmax); |     dec_data.params.kpos = computeCycleStartForDecode(computeCurrentCycle(m_TRperiod), m_TRperiod); | ||||||
|  |     symspec_(&dec_data,&k,&k0,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&ihs,&m_npts8,&m_pxmax); | ||||||
|     // 3) if symspec wants ihs to be 0, set it.
 |     // 3) if symspec wants ihs to be 0, set it.
 | ||||||
|     if(ihs == 0){ |     if(ihs == 0){ | ||||||
|         m_ihsym = ihs; |         m_ihsym = ihs; | ||||||
|     } else { |     } else { | ||||||
|         m_ihsym += 1; |         m_ihsym += 1; | ||||||
|     } |     } | ||||||
|     qDebug() << "dataSink" << k << "ihsym" << m_ihsym << "ihs" << ihs; | 
 | ||||||
|  |     // make ihsym similar to how it was...relative to the tr period
 | ||||||
|  |     m_ihsym = m_ihsym % (m_TRperiod*RX_SAMPLE_RATE/m_nsps*2); | ||||||
|  | 
 | ||||||
|  |     /// qDebug() << "dataSink" << k << "ihsym" << m_ihsym << "ihs" << ihs;
 | ||||||
|  |     /// QVector<float> sss;
 | ||||||
|  |     /// for(int i = 0; i < 10; i++){
 | ||||||
|  |     ///     sss << s[i];
 | ||||||
|  |     /// }
 | ||||||
|  |     /// qDebug() << "-->" << sss;
 | ||||||
| 
 | 
 | ||||||
|     /// END IHSYM
 |     /// END IHSYM
 | ||||||
| #else | #else | ||||||
|     symspec_(&dec_data,&k,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&m_ihsym,&m_npts8,&m_pxmax); |     m_ihsym=m_ihsym%(m_TRperiod*RX_SAMPLE_RATE/m_nsps*2); | ||||||
|  |     qDebug() << "k" << k << "k0" << k0 << "ihsym" << m_ihsym; | ||||||
|  |     symspec_(&dec_data,&k,&k0,&trmin,&nsps,&m_inGain,&nsmo,&m_px,s,&m_df3,&m_ihsym,&m_npts8,&m_pxmax); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     if(m_ihsym <= 0) return; |     if(m_ihsym <= 0) return; | ||||||
| 
 | 
 | ||||||
|     if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer
 |     if(ui) ui->signal_meter_widget->setValue(m_px,m_pxmax); // Update thermometer
 | ||||||
|     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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fixStop(); |     fixStop(); | ||||||
| @ -4140,6 +4157,31 @@ bool MainWindow::decodeReady(int submode, int period, int *pSubmode, int *pPerio | |||||||
|     strncpy(dec_data.params.hiscall,(hisCall + "            ").toLatin1 ().constData (), 12); |     strncpy(dec_data.params.hiscall,(hisCall + "            ").toLatin1 ().constData (), 12); | ||||||
|     strncpy(dec_data.params.hisgrid,(hisGrid + "      ").toLatin1 ().constData (), 6); |     strncpy(dec_data.params.hisgrid,(hisGrid + "      ").toLatin1 ().constData (), 6); | ||||||
| 
 | 
 | ||||||
|  | #if 0 | ||||||
|  |     // for waterfall computation
 | ||||||
|  |     memset(dec_data.d1, 0, sizeof(dec_data.d1)); | ||||||
|  | 
 | ||||||
|  |     int start = 0; | ||||||
|  |     int frames = 0; | ||||||
|  |     if(m_nSubMode == Varicode::JS8CallNormal){ | ||||||
|  |         start = dec_data.params.kposA; | ||||||
|  |         frames = dec_data.params.kszA; | ||||||
|  |     } | ||||||
|  |     else if(m_nSubMode == Varicode::JS8CallFast){ | ||||||
|  |         start = dec_data.params.kposB; | ||||||
|  |         frames = dec_data.params.kszB; | ||||||
|  |     } | ||||||
|  |     else if(m_nSubMode == Varicode::JS8CallTurbo){ | ||||||
|  |         start = dec_data.params.kposC; | ||||||
|  |         frames = dec_data.params.kszC; | ||||||
|  |     } | ||||||
|  |     else if(m_nSubMode == Varicode::JS8CallUltra){ | ||||||
|  |         start = dec_data.params.kposD; | ||||||
|  |         frames = dec_data.params.kszD; | ||||||
|  |     } | ||||||
|  |     memcpy(dec_data.d1, dec_data.d2 + start, sizeof(dec_data.d2[0]) * frames); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if JS8_TWO_BUFFERS | #if JS8_TWO_BUFFERS | ||||||
| #if JS8_RING_BUFFER | #if JS8_RING_BUFFER | ||||||
|     // clear out d1
 |     // clear out d1
 | ||||||
| @ -7190,12 +7232,13 @@ void MainWindow::on_actionJS8_triggered() | |||||||
|   m_TRperiod = computeSubmodePeriod(m_nSubMode); |   m_TRperiod = computeSubmodePeriod(m_nSubMode); | ||||||
|   m_wideGraph->show(); |   m_wideGraph->show(); | ||||||
|   ui->decodedTextLabel2->setText("  UTC   dB   DT Freq    Message"); |   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_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
 | ||||||
| #if JS8_RING_BUFFER | #if JS8_RING_BUFFER | ||||||
|   Q_ASSERT(NTMAX == 60); |   Q_ASSERT(NTMAX == 60); | ||||||
|  |   m_wideGraph->setPeriod(m_TRperiod, m_nsps); | ||||||
|   m_detector->setTRPeriod(NTMAX / 2); // TODO - not thread safe
 |   m_detector->setTRPeriod(NTMAX / 2); // TODO - not thread safe
 | ||||||
| #else | #else | ||||||
|  |   m_wideGraph->setPeriod(m_TRperiod, m_nsps); | ||||||
|   m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
 |   m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
 | ||||||
| #endif | #endif | ||||||
|   ui->label_7->setText("Rx Frequency"); |   ui->label_7->setText("Rx Frequency"); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jordan Sherer
						Jordan Sherer