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:
Bill Somerville 2016-06-17 01:27:00 +00:00
parent fa55dadb91
commit 2beef948d9
4 changed files with 74 additions and 44 deletions

View File

@ -11,22 +11,26 @@ extern "C" {
} }
Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds,
unsigned samplesPerFFT, unsigned downSampleFactor, unsigned downSampleFactor, QObject * parent)
QObject * parent)
: AudioDevice (parent) : AudioDevice (parent)
, m_frameRate (frameRate) , m_frameRate (frameRate)
, m_period (periodLengthInSeconds) , m_period (periodLengthInSeconds)
, m_downSampleFactor (downSampleFactor) , m_downSampleFactor (downSampleFactor)
, m_samplesPerFFT (samplesPerFFT) , m_samplesPerFFT {max_buffer_size}
, m_ns (999) , m_ns (999)
, m_buffer ((downSampleFactor > 1) ? , m_buffer ((downSampleFactor > 1) ?
new short [samplesPerFFT * downSampleFactor] : 0) new short [max_buffer_size * downSampleFactor] : nullptr)
, m_bufferPos (0) , m_bufferPos (0)
{ {
(void)m_frameRate; // quell compiler warning (void)m_frameRate; // quell compiler warning
clear (); clear ();
} }
void Detector::setBlockSize (unsigned n)
{
m_samplesPerFFT = n;
}
bool Detector::reset () bool Detector::reset ()
{ {
clear (); clear ();
@ -83,7 +87,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
if(m_bufferPos==m_samplesPerFFT*m_downSampleFactor) { if(m_bufferPos==m_samplesPerFFT*m_downSampleFactor) {
qint32 framesToProcess (m_samplesPerFFT * m_downSampleFactor); qint32 framesToProcess (m_samplesPerFFT * m_downSampleFactor);
qint32 framesAfterDownSample (m_samplesPerFFT); 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)) { dec_data.params.kin < (NTMAX*12000 - framesAfterDownSample)) {
fil4_(&m_buffer[0], &framesToProcess, &dec_data.d2[dec_data.params.kin], fil4_(&m_buffer[0], &framesToProcess, &dec_data.d2[dec_data.params.kin],
&framesAfterDownSample); &framesAfterDownSample);

View File

@ -22,12 +22,14 @@ public:
// //
// the samplesPerFFT argument is the number after down sampling // 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;} void setPeriod(unsigned p) {m_period=p;}
bool reset () override; bool reset () override;
Q_SIGNAL void framesWritten (qint64) const;
Q_SLOT void setBlockSize (unsigned);
protected: protected:
qint64 readData (char * /* data */, qint64 /* maxSize */) override qint64 readData (char * /* data */, qint64 /* maxSize */) override
{ {
@ -45,6 +47,7 @@ private:
unsigned m_downSampleFactor; unsigned m_downSampleFactor;
qint32 m_samplesPerFFT; // after any down sampling qint32 m_samplesPerFFT; // after any down sampling
qint32 m_ns; qint32 m_ns;
static size_t const max_buffer_size {7 * 512};
QScopedArrayPointer<short> m_buffer; // de-interleaved sample buffer QScopedArrayPointer<short> m_buffer; // de-interleaved sample buffer
// big enough for all the // big enough for all the
// samples for one increment of // samples for one increment of

View File

@ -164,7 +164,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
m_lastDialFreq {0}, m_lastDialFreq {0},
m_callingFrequency {0}, m_callingFrequency {0},
m_dialFreqRxWSPR {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_soundInput {new SoundInput},
m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}}, m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}},
m_soundOutput {new SoundOutput}, m_soundOutput {new SoundOutput},
@ -378,6 +379,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
connect (this, &MainWindow::finished, this, &MainWindow::close); connect (this, &MainWindow::finished, this, &MainWindow::close);
// hook up the detector signals, slots and disposal // 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_detector, &Detector::framesWritten, this, &MainWindow::dataSink);
connect (&m_audioThread, &QThread::finished, m_detector, &QObject::deleteLater); connect (&m_audioThread, &QThread::finished, m_detector, &QObject::deleteLater);
@ -995,7 +997,7 @@ void MainWindow::dataSink(qint64 frames)
} }
m_bUseRef=m_wideGraph->useRef(); 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 // Get power, spectrum, and ihsym
int trmin=m_TRperiod/60; int trmin=m_TRperiod/60;
@ -1219,7 +1221,7 @@ void MainWindow::fastSink(qint64 frames)
decodeNow=false; decodeNow=false;
m_k0=k; 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(!m_diskData and m_tRemaining<0.35 and !m_bFastDecodeCalled) decodeNow=true;
if(decodeNow) { if(decodeNow) {
@ -1824,8 +1826,7 @@ void MainWindow::on_actionDecode_remaining_files_in_directory_triggered()
void MainWindow::diskDat() //diskDat() void MainWindow::diskDat() //diskDat()
{ {
int k; int k;
// int kstep=m_nsps/2; int kstep=m_FFTSize;
int kstep=3456;
m_diskData=true; m_diskData=true;
float db=m_config.degrade(); float db=m_config.degrade();
@ -3671,6 +3672,8 @@ void MainWindow::on_actionJT9_triggered()
if(m_modeTx!="JT9") on_pbTxMode_clicked(); if(m_modeTx!="JT9") on_pbTxMode_clicked();
statusChanged(); statusChanged();
m_nsps=6912; m_nsps=6912;
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
QString t1=(QString)QChar(short(m_nSubMode+65)); QString t1=(QString)QChar(short(m_nSubMode+65));
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=179; if(m_config.decode_at_52s()) m_hsymStop=179;
@ -3729,6 +3732,8 @@ void MainWindow::on_actionJTMSK_triggered()
switch_mode (Modes::JTMSK); switch_mode (Modes::JTMSK);
statusChanged(); statusChanged();
m_nsps=6; m_nsps=6;
m_FFTSize = 7 * 512;
Q_EMIT FFTSize (m_FFTSize);
mode_label->setStyleSheet("QLabel{background-color: #ff6666}"); mode_label->setStyleSheet("QLabel{background-color: #ff6666}");
mode_label->setText(m_mode); mode_label->setText(m_mode);
m_toneSpacing=0.0; m_toneSpacing=0.0;
@ -3770,6 +3775,8 @@ void MainWindow::on_actionMSK144_triggered()
switch_mode (Modes::MSK144); switch_mode (Modes::MSK144);
statusChanged(); statusChanged();
m_nsps=6; m_nsps=6;
m_FFTSize = 7 * 512;
Q_EMIT FFTSize (m_FFTSize);
mode_label->setStyleSheet("QLabel{background-color: #ff6666}"); mode_label->setStyleSheet("QLabel{background-color: #ff6666}");
mode_label->setText(m_mode); mode_label->setText(m_mode);
m_toneSpacing=0.0; m_toneSpacing=0.0;
@ -3810,6 +3817,8 @@ void MainWindow::on_actionJT65_triggered()
m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setPeriod(m_TRperiod); // TODO - not thread safe m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=179; if(m_config.decode_at_52s()) m_hsymStop=179;
m_toneSpacing=0.0; m_toneSpacing=0.0;
@ -3860,6 +3869,8 @@ void MainWindow::on_actionJT9_JT65_triggered()
m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setPeriod(m_TRperiod); // TODO - not thread safe m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; m_nsps=6912;
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=173; m_hsymStop=173;
if(m_config.decode_at_52s()) m_hsymStop=179; if(m_config.decode_at_52s()) m_hsymStop=179;
m_toneSpacing=0.0; m_toneSpacing=0.0;
@ -3894,6 +3905,8 @@ void MainWindow::on_actionJT4_triggered()
m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setPeriod(m_TRperiod); // TODO - not thread safe m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=179; m_hsymStop=179;
m_toneSpacing=0.0; m_toneSpacing=0.0;
ui->actionJT4->setChecked(true); ui->actionJT4->setChecked(true);
@ -3937,6 +3950,8 @@ void MainWindow::on_actionWSPR_2_triggered()
m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe m_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setPeriod(m_TRperiod); // TODO - not thread safe m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=396; m_hsymStop=396;
m_toneSpacing=12000.0/8192.0; m_toneSpacing=12000.0/8192.0;
mode_label->setStyleSheet("QLabel{background-color: #ff66ff}"); 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_modulator->setPeriod(m_TRperiod); // TODO - not thread safe
m_detector->setPeriod(m_TRperiod); // TODO - not thread safe m_detector->setPeriod(m_TRperiod); // TODO - not thread safe
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=10; m_hsymStop=10;
m_toneSpacing=1.0; m_toneSpacing=1.0;
switch_mode(Modes::Echo); switch_mode(Modes::Echo);
@ -4001,6 +4018,8 @@ void MainWindow::on_actionISCAT_triggered()
m_detector->setPeriod(m_TRperiod); m_detector->setPeriod(m_TRperiod);
m_wideGraph->setPeriod(m_TRperiod,m_nsps); m_wideGraph->setPeriod(m_TRperiod,m_nsps);
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
m_hsymStop=103; m_hsymStop=103;
m_toneSpacing=11025.0/256.0; m_toneSpacing=11025.0/256.0;
WSPR_config(false); WSPR_config(false);
@ -4699,6 +4718,8 @@ void MainWindow::transmit (double snr)
if (m_modeTx == "JTMSK" or m_modeTx == "MSK144") { if (m_modeTx == "JTMSK" or m_modeTx == "MSK144") {
m_nsps=6; m_nsps=6;
m_FFTSize = 7 * 512;
Q_EMIT FFTSize (m_FFTSize);
m_toneSpacing=6000.0/m_nsps; m_toneSpacing=6000.0/m_nsps;
double f0=1000.0; double f0=1000.0;
int nsym; int nsym;

View File

@ -260,6 +260,7 @@ private:
Q_SIGNAL void suspendAudioInputStream () const; Q_SIGNAL void suspendAudioInputStream () const;
Q_SIGNAL void resumeAudioInputStream () const; Q_SIGNAL void resumeAudioInputStream () const;
Q_SIGNAL void startDetector (AudioDevice::Channel) const; Q_SIGNAL void startDetector (AudioDevice::Channel) const;
Q_SIGNAL void FFTSize (unsigned) const;
Q_SIGNAL void detectorClose () const; Q_SIGNAL void detectorClose () const;
Q_SIGNAL void finished () const; Q_SIGNAL void finished () const;
Q_SIGNAL void transmitFrequency (double) const; Q_SIGNAL void transmitFrequency (double) const;
@ -308,6 +309,7 @@ private:
Frequency m_dialFreqRxWSPR; // best guess at WSPR QRG Frequency m_dialFreqRxWSPR; // best guess at WSPR QRG
Detector * m_detector; Detector * m_detector;
unsigned m_FFTSize;
SoundInput * m_soundInput; SoundInput * m_soundInput;
Modulator * m_modulator; Modulator * m_modulator;
SoundOutput * m_soundOutput; SoundOutput * m_soundOutput;