mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	Adaptive sample block size to match FFT sizes
This change corrects timing discrepancies on the horizontal fast spectrum plot. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6780 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
		
							parent
							
								
									fa55dadb91
								
							
						
					
					
						commit
						2beef948d9
					
				
							
								
								
									
										14
									
								
								Detector.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Detector.cpp
									
									
									
									
									
								
							| @ -11,22 +11,26 @@ extern "C" { | ||||
| } | ||||
| 
 | ||||
| Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, | ||||
|                     unsigned samplesPerFFT, unsigned downSampleFactor, | ||||
|                     QObject * parent) | ||||
|                     unsigned downSampleFactor, QObject * parent) | ||||
|   : AudioDevice (parent) | ||||
|   , m_frameRate (frameRate) | ||||
|   , m_period (periodLengthInSeconds) | ||||
|   , m_downSampleFactor (downSampleFactor) | ||||
|   , m_samplesPerFFT (samplesPerFFT) | ||||
|   , m_samplesPerFFT {max_buffer_size} | ||||
|   , m_ns (999) | ||||
|   , m_buffer ((downSampleFactor > 1) ? | ||||
|               new short [samplesPerFFT * downSampleFactor] : 0) | ||||
|               new short [max_buffer_size * downSampleFactor] : nullptr) | ||||
|   , m_bufferPos (0) | ||||
| { | ||||
|   (void)m_frameRate;            // quell compiler warning
 | ||||
|   clear (); | ||||
| } | ||||
| 
 | ||||
| void Detector::setBlockSize (unsigned n) | ||||
| { | ||||
|   m_samplesPerFFT = n; | ||||
| } | ||||
| 
 | ||||
| bool Detector::reset () | ||||
| { | ||||
|   clear (); | ||||
| @ -83,7 +87,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize) | ||||
|         if(m_bufferPos==m_samplesPerFFT*m_downSampleFactor) { | ||||
|           qint32 framesToProcess (m_samplesPerFFT * m_downSampleFactor); | ||||
|           qint32 framesAfterDownSample (m_samplesPerFFT); | ||||
|           if(framesToProcess==13824 and dec_data.params.kin>=0 and | ||||
|           if(m_downSampleFactor > 1 && dec_data.params.kin>=0 && | ||||
|              dec_data.params.kin < (NTMAX*12000 - framesAfterDownSample)) { | ||||
|             fil4_(&m_buffer[0], &framesToProcess, &dec_data.d2[dec_data.params.kin], | ||||
|                   &framesAfterDownSample); | ||||
|  | ||||
| @ -22,12 +22,14 @@ public: | ||||
|   //
 | ||||
|   // the samplesPerFFT argument is the number after down sampling
 | ||||
|   //
 | ||||
|   Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned samplesPerFFT, unsigned downSampleFactor = 4u, QObject * parent = 0); | ||||
|   Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0); | ||||
| 
 | ||||
|   Q_SIGNAL void framesWritten (qint64) const; | ||||
|   void setPeriod(unsigned p) {m_period=p;} | ||||
|   bool reset () override; | ||||
| 
 | ||||
|   Q_SIGNAL void framesWritten (qint64) const; | ||||
|   Q_SLOT void setBlockSize (unsigned); | ||||
| 
 | ||||
| protected: | ||||
|   qint64 readData (char * /* data */, qint64 /* maxSize */) override | ||||
|   { | ||||
| @ -45,6 +47,7 @@ private: | ||||
|   unsigned m_downSampleFactor; | ||||
|   qint32 m_samplesPerFFT;	// after any down sampling
 | ||||
|   qint32 m_ns; | ||||
|   static size_t const max_buffer_size {7 * 512}; | ||||
|   QScopedArrayPointer<short> m_buffer; // de-interleaved sample buffer
 | ||||
|   // big enough for all the
 | ||||
|   // samples for one increment of
 | ||||
|  | ||||
| @ -164,7 +164,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, | ||||
|   m_lastDialFreq {0}, | ||||
|   m_callingFrequency {0}, | ||||
|   m_dialFreqRxWSPR {0}, | ||||
|   m_detector {new Detector {RX_SAMPLE_RATE, NTMAX, 6912 / 2, downSampleFactor}}, | ||||
|   m_detector {new Detector {RX_SAMPLE_RATE, NTMAX, downSampleFactor}}, | ||||
|   m_FFTSize {6192 / 2},         // conservative value to avoid buffer overruns
 | ||||
|   m_soundInput {new SoundInput}, | ||||
|   m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}}, | ||||
|   m_soundOutput {new SoundOutput}, | ||||
| @ -378,6 +379,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, | ||||
|   connect (this, &MainWindow::finished, this, &MainWindow::close); | ||||
| 
 | ||||
|   // hook up the detector signals, slots and disposal
 | ||||
|   connect (this, &MainWindow::FFTSize, m_detector, &Detector::setBlockSize); | ||||
|   connect(m_detector, &Detector::framesWritten, this, &MainWindow::dataSink); | ||||
|   connect (&m_audioThread, &QThread::finished, m_detector, &QObject::deleteLater); | ||||
| 
 | ||||
| @ -995,7 +997,7 @@ void MainWindow::dataSink(qint64 frames) | ||||
|   } | ||||
| 
 | ||||
|   m_bUseRef=m_wideGraph->useRef(); | ||||
|   refspectrum_(&dec_data.d2[k-3456],&m_bRefSpec,&m_bUseRef,c_fname,len); | ||||
|   refspectrum_(&dec_data.d2[k-m_nsps/2],&m_bRefSpec,&m_bUseRef,c_fname,len); | ||||
| 
 | ||||
| // Get power, spectrum, and ihsym
 | ||||
|   int trmin=m_TRperiod/60; | ||||
| @ -1219,7 +1221,7 @@ void MainWindow::fastSink(qint64 frames) | ||||
| 
 | ||||
|   decodeNow=false; | ||||
|   m_k0=k; | ||||
|   if(m_diskData and m_k0 >= dec_data.params.kin-3456) decodeNow=true; | ||||
|   if(m_diskData and m_k0 >= dec_data.params.kin - 7 * 512) decodeNow=true; | ||||
|   if(!m_diskData and m_tRemaining<0.35 and !m_bFastDecodeCalled) decodeNow=true; | ||||
| 
 | ||||
|   if(decodeNow) { | ||||
| @ -1753,39 +1755,39 @@ void MainWindow::read_wav_file (QString const& fname) | ||||
| { | ||||
|   // call diskDat() when done
 | ||||
|   m_wav_future_watcher.setFuture (QtConcurrent::run ([this, fname] { | ||||
| 	auto basename = fname.mid (fname.lastIndexOf ('/') + 1); | ||||
| 	auto pos = fname.indexOf (".wav", 0, Qt::CaseInsensitive); | ||||
| 	// global variables and threads do not mix well, this needs changing
 | ||||
| 	dec_data.params.nutc = 0; | ||||
| 	if (pos > 0) | ||||
| 	  { | ||||
| 	    if (pos == fname.indexOf ('_', -11) + 7) | ||||
| 	      { | ||||
| 		dec_data.params.nutc = fname.mid (pos - 6, 6).toInt (); | ||||
| 	      } | ||||
| 	    else | ||||
| 	      { | ||||
| 		dec_data.params.nutc = 100 * fname.mid (pos - 4, 4).toInt (); | ||||
| 	      } | ||||
| 	  } | ||||
| 	BWFFile file {QAudioFormat {}, fname}; | ||||
| 	file.open (BWFFile::ReadOnly); | ||||
| 	auto bytes_per_frame = file.format ().bytesPerFrame (); | ||||
| 	qint64 max_bytes = std::min (std::size_t (m_TRperiod * RX_SAMPLE_RATE), | ||||
| 				     sizeof (dec_data.d2) / sizeof (dec_data.d2[0])) | ||||
|         auto basename = fname.mid (fname.lastIndexOf ('/') + 1); | ||||
|         auto pos = fname.indexOf (".wav", 0, Qt::CaseInsensitive); | ||||
|         // global variables and threads do not mix well, this needs changing
 | ||||
|         dec_data.params.nutc = 0; | ||||
|         if (pos > 0) | ||||
|           { | ||||
|             if (pos == fname.indexOf ('_', -11) + 7) | ||||
|               { | ||||
|                 dec_data.params.nutc = fname.mid (pos - 6, 6).toInt (); | ||||
|               } | ||||
|             else | ||||
|               { | ||||
|                 dec_data.params.nutc = 100 * fname.mid (pos - 4, 4).toInt (); | ||||
|               } | ||||
|           } | ||||
|         BWFFile file {QAudioFormat {}, fname}; | ||||
|         file.open (BWFFile::ReadOnly); | ||||
|         auto bytes_per_frame = file.format ().bytesPerFrame (); | ||||
|         qint64 max_bytes = std::min (std::size_t (m_TRperiod * RX_SAMPLE_RATE), | ||||
|                                      sizeof (dec_data.d2) / sizeof (dec_data.d2[0])) | ||||
|           * bytes_per_frame; | ||||
| 	auto n = file.read (reinterpret_cast<char *> (dec_data.d2), | ||||
| 			    std::min (max_bytes, file.size ())); | ||||
| 	int frames_read = n / bytes_per_frame; | ||||
| 	// zero unfilled remaining sample space
 | ||||
| 	std::memset (&dec_data.d2[0] + n, 0, max_bytes - n); | ||||
| 	if (11025 == file.format ().sampleRate ()) | ||||
| 	  { | ||||
|           short sample_size = file.format ().sampleSize (); | ||||
|           wav12_ (dec_data.d2, dec_data.d2, &frames_read, &sample_size); | ||||
| 	  } | ||||
| 	dec_data.params.kin = frames_read; | ||||
| 	dec_data.params.newdat = 1; | ||||
|         auto n = file.read (reinterpret_cast<char *> (dec_data.d2), | ||||
|                             std::min (max_bytes, file.size ())); | ||||
|         int frames_read = n / bytes_per_frame; | ||||
|         // zero unfilled remaining sample space
 | ||||
|         std::memset (&dec_data.d2[0] + n, 0, max_bytes - n); | ||||
|         if (11025 == file.format ().sampleRate ()) | ||||
|           { | ||||
|             short sample_size = file.format ().sampleSize (); | ||||
|             wav12_ (dec_data.d2, dec_data.d2, &frames_read, &sample_size); | ||||
|           } | ||||
|         dec_data.params.kin = frames_read; | ||||
|         dec_data.params.newdat = 1; | ||||
|       })); | ||||
| } | ||||
| 
 | ||||
| @ -1824,8 +1826,7 @@ void MainWindow::on_actionDecode_remaining_files_in_directory_triggered() | ||||
| void MainWindow::diskDat()                                   //diskDat()
 | ||||
| { | ||||
|   int k; | ||||
| //  int kstep=m_nsps/2;
 | ||||
|   int kstep=3456; | ||||
|   int kstep=m_FFTSize; | ||||
|   m_diskData=true; | ||||
| 
 | ||||
|   float db=m_config.degrade(); | ||||
| @ -3671,6 +3672,8 @@ void MainWindow::on_actionJT9_triggered() | ||||
|   if(m_modeTx!="JT9") on_pbTxMode_clicked(); | ||||
|   statusChanged(); | ||||
|   m_nsps=6912; | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   QString t1=(QString)QChar(short(m_nSubMode+65)); | ||||
|   m_hsymStop=173; | ||||
|   if(m_config.decode_at_52s()) m_hsymStop=179; | ||||
| @ -3729,6 +3732,8 @@ void MainWindow::on_actionJTMSK_triggered() | ||||
|   switch_mode (Modes::JTMSK); | ||||
|   statusChanged(); | ||||
|   m_nsps=6; | ||||
|   m_FFTSize = 7 * 512; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   mode_label->setStyleSheet("QLabel{background-color: #ff6666}"); | ||||
|   mode_label->setText(m_mode); | ||||
|   m_toneSpacing=0.0; | ||||
| @ -3770,6 +3775,8 @@ void MainWindow::on_actionMSK144_triggered() | ||||
|   switch_mode (Modes::MSK144); | ||||
|   statusChanged(); | ||||
|   m_nsps=6; | ||||
|   m_FFTSize = 7 * 512; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   mode_label->setStyleSheet("QLabel{background-color: #ff6666}"); | ||||
|   mode_label->setText(m_mode); | ||||
|   m_toneSpacing=0.0; | ||||
| @ -3810,6 +3817,8 @@ void MainWindow::on_actionJT65_triggered() | ||||
|   m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
 | ||||
|   m_detector->setPeriod(m_TRperiod);   // TODO - not thread safe
 | ||||
|   m_nsps=6912;                   //For symspec only
 | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=173; | ||||
|   if(m_config.decode_at_52s()) m_hsymStop=179; | ||||
|   m_toneSpacing=0.0; | ||||
| @ -3860,6 +3869,8 @@ void MainWindow::on_actionJT9_JT65_triggered() | ||||
|   m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
 | ||||
|   m_detector->setPeriod(m_TRperiod);  // TODO - not thread safe
 | ||||
|   m_nsps=6912; | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=173; | ||||
|   if(m_config.decode_at_52s()) m_hsymStop=179; | ||||
|   m_toneSpacing=0.0; | ||||
| @ -3894,6 +3905,8 @@ void MainWindow::on_actionJT4_triggered() | ||||
|   m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
 | ||||
|   m_detector->setPeriod(m_TRperiod);  // TODO - not thread safe
 | ||||
|   m_nsps=6912;                   //For symspec only
 | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=179; | ||||
|   m_toneSpacing=0.0; | ||||
|   ui->actionJT4->setChecked(true); | ||||
| @ -3937,6 +3950,8 @@ void MainWindow::on_actionWSPR_2_triggered() | ||||
|   m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
 | ||||
|   m_detector->setPeriod(m_TRperiod);  // TODO - not thread safe
 | ||||
|   m_nsps=6912;                   //For symspec only
 | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=396; | ||||
|   m_toneSpacing=12000.0/8192.0; | ||||
|   mode_label->setStyleSheet("QLabel{background-color: #ff66ff}"); | ||||
| @ -3970,6 +3985,8 @@ void MainWindow::on_actionEcho_triggered() | ||||
|   m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
 | ||||
|   m_detector->setPeriod(m_TRperiod);  // TODO - not thread safe
 | ||||
|   m_nsps=6912;                   //For symspec only
 | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=10; | ||||
|   m_toneSpacing=1.0; | ||||
|   switch_mode(Modes::Echo); | ||||
| @ -4001,6 +4018,8 @@ void MainWindow::on_actionISCAT_triggered() | ||||
|   m_detector->setPeriod(m_TRperiod); | ||||
|   m_wideGraph->setPeriod(m_TRperiod,m_nsps); | ||||
|   m_nsps=6912;                   //For symspec only
 | ||||
|   m_FFTSize = m_nsps / 2; | ||||
|   Q_EMIT FFTSize (m_FFTSize); | ||||
|   m_hsymStop=103; | ||||
|   m_toneSpacing=11025.0/256.0; | ||||
|   WSPR_config(false); | ||||
| @ -4699,6 +4718,8 @@ void MainWindow::transmit (double snr) | ||||
| 
 | ||||
|   if (m_modeTx == "JTMSK" or m_modeTx == "MSK144") { | ||||
|     m_nsps=6; | ||||
|     m_FFTSize = 7 * 512; | ||||
|     Q_EMIT FFTSize (m_FFTSize); | ||||
|     m_toneSpacing=6000.0/m_nsps; | ||||
|     double f0=1000.0; | ||||
|     int nsym; | ||||
|  | ||||
| @ -260,6 +260,7 @@ private: | ||||
|   Q_SIGNAL void suspendAudioInputStream () const; | ||||
|   Q_SIGNAL void resumeAudioInputStream () const; | ||||
|   Q_SIGNAL void startDetector (AudioDevice::Channel) const; | ||||
|   Q_SIGNAL void FFTSize (unsigned) const; | ||||
|   Q_SIGNAL void detectorClose () const; | ||||
|   Q_SIGNAL void finished () const; | ||||
|   Q_SIGNAL void transmitFrequency (double) const; | ||||
| @ -308,6 +309,7 @@ private: | ||||
|   Frequency  m_dialFreqRxWSPR;  // best guess at WSPR QRG
 | ||||
| 
 | ||||
|   Detector * m_detector; | ||||
|   unsigned m_FFTSize; | ||||
|   SoundInput * m_soundInput; | ||||
|   Modulator * m_modulator; | ||||
|   SoundOutput * m_soundOutput; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user