Fix some timing issues resulting from non-integral m_TRperiod for FT4.

This commit is contained in:
Joe Taylor 2019-05-23 13:24:35 -04:00
parent 37291ff64c
commit dfedc40db1
4 changed files with 25 additions and 42 deletions

View File

@ -55,12 +55,14 @@ void Detector::clear ()
qint64 Detector::writeData (char const * data, qint64 maxSize)
{
int ns=secondInPeriod();
if(ns < m_ns) { // When ns has wrapped around to zero, restart the buffers
static unsigned mstr0=999999;
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time
if(mstr < mstr0) { //When mstr has wrapped around to 0, restart the buffer
dec_data.params.kin = 0;
m_bufferPos = 0;
}
m_ns=ns;
mstr0=mstr;
// no torn frames
Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ())));
@ -73,7 +75,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
if (framesAccepted < static_cast<size_t> (maxSize / bytesPerFrame ())) {
qDebug () << "dropped " << maxSize / bytesPerFrame () - framesAccepted
<< " frames of data on the floor!"
<< dec_data.params.kin << ns;
<< dec_data.params.kin << mstr;
}
for (unsigned remaining = framesAccepted; remaining; ) {
@ -121,14 +123,3 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
return maxSize; // we drop any data past the end of the buffer on
// the floor until the next period starts
}
unsigned Detector::secondInPeriod () const
{
// we take the time of the data as the following assuming no latency
// delivering it to us (not true but close enough for us)
qint64 now (QDateTime::currentMSecsSinceEpoch ());
unsigned secondInToday ((now % 86400000LL) / 1000);
unsigned secInPeriod = fmod(double(secondInToday),m_period);
return secInPeriod;
}

View File

@ -41,7 +41,6 @@ protected:
private:
void clear (); // discard buffer contents
unsigned secondInPeriod () const;
unsigned m_frameRate;
double m_period;

View File

@ -32,8 +32,8 @@ Modulator::Modulator (unsigned frameRate, double periodLengthInSeconds,
, m_phi {0.0}
, m_toneSpacing {0.0}
, m_fSpread {0.0}
, m_frameRate {frameRate}
, m_period {periodLengthInSeconds}
, m_frameRate {frameRate}
, m_state {Idle}
, m_tuning {false}
, m_cwLevel {false}
@ -50,13 +50,10 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
Q_ASSERT (stream);
// Time according to this computer which becomes our base time
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time
// qDebug() << "ModStart" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.sss");
if(m_state != Idle) stop ();
if(m_state != Idle) stop();
m_quickClose = false;
m_symbolsLength = symbolsLength;
m_isym0 = std::numeric_limits<unsigned>::max (); // big number
m_frequency0 = 0.;
@ -68,37 +65,33 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
m_toneSpacing = toneSpacing;
m_bFastMode=fastMode;
m_TRperiod=TRperiod;
unsigned delay_ms = 1920 == m_nsps && 15 == m_period ? 500 : 1000;
unsigned delay_ms=1000;
if(m_nsps==1920) delay_ms=500; //FT8
if(m_nsps==576) delay_ms=300; //FT4
// noise generator parameters
// noise generator parameters
if (m_addNoise) {
m_snr = qPow (10.0, 0.05 * (dBSNR - 6.0));
m_fac = 3000.0;
if (m_snr > 1.0) m_fac = 3000.0 / m_snr;
}
unsigned mstr = ms0 % int(1000.0*m_period); // ms in period
// round up to an exact portion of a second that allows for startup
// delays
// round up to an exact portion of a second that allows for startup delays
m_ic = (mstr / delay_ms) * m_frameRate * delay_ms / 1000;
if(m_bFastMode) m_ic=0;
m_silentFrames = 0;
// calculate number of silent frames to send, so that audio will start at
// the nominal time "delay_ms" into the Tx sequence.
// calculate number of silent frames to send, so that audio will start at
// the nominal time "delay_ms" into the Tx sequence.
if (synchronize && !m_tuning && !m_bFastMode) {
m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000));
}
if(symbolsLength==105 and framesPerSymbol==576
and (toneSpacing==12000.0/576.0 or toneSpacing==-2.0)) {
//### FT4 parameters
m_ic=0;
m_silentFrames=0;
}
// qDebug() << "Mod AA" << symbolsLength << framesPerSymbol << toneSpacing;
// qDebug() << "Mod AB" << delay_ms << mstr << m_ic << m_silentFrames;
// qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz")
// << m_ic << m_silentFrames << m_silentFrames/48000.0
// << mstr << fmod(double(ms0),1000.0*m_period);
initialize (QIODevice::ReadOnly, channel);
Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ?

View File

@ -2838,12 +2838,12 @@ void MainWindow::decode() //decode()
dec_data.params.nutc=100*ihr + imin;
if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9 or m_mode=="FT8" or m_mode=="FT4") {
qint64 ms=1000.0*(2.0-m_TRperiod);
if(m_mode=="FT4") ms=1000.0*(3.0-m_TRperiod);
if(m_mode=="FT4") ms=1000.0*(2.0-m_TRperiod);
QDateTime t=QDateTime::currentDateTimeUtc().addMSecs(ms);
ihr=t.toString("hh").toInt();
imin=t.toString("mm").toInt();
int isec=t.toString("ss").toInt();
if(m_mode!="FT4") isec=isec - fmod(double(isec),m_TRperiod);
isec=isec - fmod(double(isec),m_TRperiod);
dec_data.params.nutc=10000*ihr + 100*imin + isec;
}
}
@ -3498,9 +3498,9 @@ void MainWindow::guiUpdate()
if(m_transmitting or m_auto or m_tune) {
m_dateTimeLastTX = QDateTime::currentDateTimeUtc ();
// Check for "txboth" (testing purposes only)
// Check for "txboth" (FT4 testing purposes only)
QFile f(m_appDir + "/txboth");
if(f.exists() and fmod(tsec,m_TRperiod) < (1.0 + 85.0*m_nsps/12000.0)) m_bTxTime=true;
if(f.exists() and fmod(tsec,m_TRperiod) < (0.5 + 105.0*576.0/12000.0)) m_bTxTime=true;
// Don't transmit another mode in the 30 m WSPR sub-band
Frequency onAirFreq = m_freqNominal + ui->TxFreqSpinBox->value();