mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-27 06:38:44 -05:00
Replaced Detector monitoring switch with audio stream suspend/resume.
In an effort to reduce the processing overhead when transmitting I have suspended the audio input stream at source instead of the prior behavior that simply idled skipping received samples. This is in response to high activity levels, especially with JTAlert also running, when decode processing rolls over into the next TX period. Tests show a reduction in CPU loading from ~5% to ~1.5% in the above scenario. Hopefully this will reduce the likelyhood of TX audio glitches when other system activity spikes. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3986 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
f8bdff9aa7
commit
c3d1eb5cee
@ -26,7 +26,7 @@ public:
|
||||
|
||||
bool initialize (OpenMode mode, Channel channel);
|
||||
|
||||
bool isSequential () const {return true;}
|
||||
bool isSequential () const override {return true;}
|
||||
|
||||
size_t bytesPerFrame () const {return sizeof (qint16) * (Mono == m_channel ? 1 : 2);}
|
||||
|
||||
|
20
Detector.cpp
20
Detector.cpp
@ -18,7 +18,6 @@ Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds,
|
||||
, m_period (periodLengthInSeconds)
|
||||
, m_downSampleFactor (downSampleFactor)
|
||||
, m_framesPerSignal (framesPerSignal)
|
||||
, m_monitoring (false)
|
||||
, m_starting (false)
|
||||
, m_buffer ((downSampleFactor > 1) ?
|
||||
new short [framesPerSignal * downSampleFactor] : 0)
|
||||
@ -31,7 +30,9 @@ Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds,
|
||||
bool Detector::reset ()
|
||||
{
|
||||
clear ();
|
||||
return QIODevice::reset ();
|
||||
// don't call base call reset because it calls seek(0) which causes
|
||||
// a warning
|
||||
return isOpen ();
|
||||
}
|
||||
|
||||
void Detector::clear ()
|
||||
@ -41,6 +42,7 @@ void Detector::clear ()
|
||||
// unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
||||
// jt9com_.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (jt9com_.d2) / sizeof (jt9com_.d2[0])));
|
||||
jt9com_.kin = 0;
|
||||
m_bufferPos = 0;
|
||||
|
||||
// fill buffer with zeros (G4WJS commented out because it might cause decoder hangs)
|
||||
// qFill (jt9com_.d2, jt9com_.d2 + sizeof (jt9com_.d2) / sizeof (jt9com_.d2[0]), 0);
|
||||
@ -48,7 +50,6 @@ void Detector::clear ()
|
||||
|
||||
qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
{
|
||||
if (m_monitoring) {
|
||||
// no torn frames
|
||||
Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ())));
|
||||
// these are in terms of input frames (not down sampled)
|
||||
@ -70,7 +71,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
store (&data[(framesAccepted - remaining) * bytesPerFrame ()],
|
||||
numFramesProcessed, &m_buffer[m_bufferPos]);
|
||||
m_bufferPos += numFramesProcessed;
|
||||
if(m_bufferPos==m_framesPerSignal*m_downSampleFactor && m_monitoring) {
|
||||
if(m_bufferPos==m_framesPerSignal*m_downSampleFactor) {
|
||||
qint32 framesToProcess (m_framesPerSignal * m_downSampleFactor);
|
||||
qint32 framesAfterDownSample;
|
||||
if(framesToProcess==13824 and jt9com_.kin>=0 and jt9com_.kin<1440000) {
|
||||
@ -91,8 +92,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
numFramesProcessed, &jt9com_.d2[jt9com_.kin]);
|
||||
m_bufferPos += numFramesProcessed;
|
||||
jt9com_.kin += numFramesProcessed;
|
||||
if (m_bufferPos == static_cast<unsigned> (m_framesPerSignal) &&
|
||||
m_monitoring) {
|
||||
if (m_bufferPos == static_cast<unsigned> (m_framesPerSignal)) {
|
||||
Q_EMIT framesWritten (jt9com_.kin);
|
||||
m_bufferPos = 0;
|
||||
}
|
||||
@ -114,10 +114,10 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
}
|
||||
remaining -= numFramesProcessed;
|
||||
}
|
||||
} else {
|
||||
jt9com_.kin = 0;
|
||||
m_bufferPos = 0;
|
||||
}
|
||||
// } else {
|
||||
// jt9com_.kin = 0;
|
||||
// m_bufferPos = 0;
|
||||
// }
|
||||
|
||||
return maxSize; // we drop any data past the end of the buffer on
|
||||
// the floor until the next period starts
|
||||
|
10
Detector.hpp
10
Detector.hpp
@ -15,8 +15,6 @@ class Detector : public AudioDevice
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
Q_PROPERTY (bool monitoring READ isMonitoring WRITE setMonitoring);
|
||||
|
||||
public:
|
||||
//
|
||||
// if the data buffer were not global storage and fixed size then we
|
||||
@ -28,13 +26,10 @@ public:
|
||||
//
|
||||
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned framesPerSignal, unsigned downSampleFactor = 4u, QObject * parent = 0);
|
||||
|
||||
bool isMonitoring () const {return m_monitoring;}
|
||||
|
||||
Q_SLOT void setMonitoring (bool newState) {m_monitoring = newState; m_bufferPos = 0;}
|
||||
Q_SLOT bool reset ();
|
||||
|
||||
Q_SIGNAL void framesWritten (qint64) const;
|
||||
|
||||
bool reset () override;
|
||||
|
||||
protected:
|
||||
qint64 readData (char * /* data */, qint64 /* maxSize */)
|
||||
{
|
||||
@ -51,7 +46,6 @@ private:
|
||||
unsigned m_period;
|
||||
unsigned m_downSampleFactor;
|
||||
qint32 m_framesPerSignal; // after any down sampling
|
||||
bool volatile m_monitoring;
|
||||
bool m_starting;
|
||||
QScopedArrayPointer<short> m_buffer; // de-interleaved sample buffer
|
||||
// big enough for all the
|
||||
|
@ -146,6 +146,8 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
|
||||
|
||||
// hook up the audio input stream
|
||||
connect (this, &MainWindow::startAudioInputStream, &m_soundInput, &SoundInput::start);
|
||||
connect (this, &MainWindow::suspendAudioInputStream, &m_soundInput, &SoundInput::suspend);
|
||||
connect (this, &MainWindow::resumeAudioInputStream, &m_soundInput, &SoundInput::resume);
|
||||
connect (this, &MainWindow::finished, &m_soundInput, &SoundInput::stop);
|
||||
|
||||
connect (this, &MainWindow::finished, this, &MainWindow::close);
|
||||
@ -154,7 +156,6 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
|
||||
// connect(&m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage);
|
||||
|
||||
// hook up the detector
|
||||
connect (this, &MainWindow::detectorSetMonitoring, &m_detector, &Detector::setMonitoring);
|
||||
connect(&m_detector, &Detector::framesWritten, this, &MainWindow::dataSink);
|
||||
|
||||
// setup the waterfall
|
||||
@ -672,20 +673,19 @@ void MainWindow::on_monitorButton_clicked (bool checked)
|
||||
if (!m_transmitting)
|
||||
{
|
||||
m_monitoring = checked;
|
||||
|
||||
if (checked)
|
||||
if (m_monitoring)
|
||||
{
|
||||
m_diskData = false; // no longer reading WAV files
|
||||
|
||||
if (m_monitoring)
|
||||
{
|
||||
// put rig back where it was when last in control
|
||||
Q_EMIT m_config.transceiver_frequency (m_lastMonitoredFrequency);
|
||||
setXIT (m_txFreq);
|
||||
}
|
||||
// put rig back where it was when last in control
|
||||
Q_EMIT m_config.transceiver_frequency (m_lastMonitoredFrequency);
|
||||
setXIT (m_txFreq);
|
||||
Q_EMIT resumeAudioInputStream ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT suspendAudioInputStream ();
|
||||
}
|
||||
|
||||
Q_EMIT detectorSetMonitoring (checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -985,8 +985,6 @@ void MainWindow::closeEvent(QCloseEvent * e)
|
||||
|
||||
void MainWindow::on_stopButton_clicked() //stopButton
|
||||
{
|
||||
// m_monitoring=false;
|
||||
// Q_EMIT detectorSetMonitoring (m_monitoring);
|
||||
monitor (false);
|
||||
m_loopall=false;
|
||||
}
|
||||
@ -1023,8 +1021,6 @@ void MainWindow::on_actionAstronomical_data_triggered()
|
||||
|
||||
void MainWindow::on_actionOpen_triggered() //Open File
|
||||
{
|
||||
// m_monitoring=false;
|
||||
// Q_EMIT detectorSetMonitoring (m_monitoring);
|
||||
monitor (false);
|
||||
|
||||
QString fname;
|
||||
@ -1576,8 +1572,6 @@ void MainWindow::guiUpdate()
|
||||
|
||||
signalMeter->setValue(0);
|
||||
|
||||
// m_monitoring=false;
|
||||
// Q_EMIT detectorSetMonitoring (false);
|
||||
if (m_monitoring)
|
||||
{
|
||||
monitor (false);
|
||||
|
@ -181,9 +181,10 @@ private:
|
||||
Q_SIGNAL void stopAudioOutputStream () const;
|
||||
|
||||
Q_SIGNAL void startAudioInputStream (QAudioDeviceInfo const&, int framesPerBuffer, AudioDevice * sink, unsigned downSampleFactor, AudioDevice::Channel) const;
|
||||
Q_SIGNAL void suspendAudioInputStream () const;
|
||||
Q_SIGNAL void resumeAudioInputStream () const;
|
||||
|
||||
Q_SIGNAL void startDetector (AudioDevice::Channel) const;
|
||||
Q_SIGNAL void detectorSetMonitoring (bool) const;
|
||||
Q_SIGNAL void detectorClose () const;
|
||||
|
||||
Q_SIGNAL void finished () const;
|
||||
|
25
soundin.cpp
25
soundin.cpp
@ -88,8 +88,33 @@ void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, Audi
|
||||
}
|
||||
}
|
||||
|
||||
void SoundInput::suspend ()
|
||||
{
|
||||
if (m_stream)
|
||||
{
|
||||
m_stream->suspend ();
|
||||
audioError ();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundInput::resume ()
|
||||
{
|
||||
if (m_sink)
|
||||
{
|
||||
m_sink->reset ();
|
||||
}
|
||||
|
||||
if (m_stream)
|
||||
{
|
||||
m_stream->resume ();
|
||||
audioError ();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundInput::handleStateChanged (QAudio::State newState) const
|
||||
{
|
||||
// qDebug () << "SoundInput::handleStateChanged: newState:" << newState;
|
||||
|
||||
switch (newState)
|
||||
{
|
||||
case QAudio::IdleState:
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
// sink must exist from the start call until the next start call or
|
||||
// stop call
|
||||
Q_SLOT void start(QAudioDeviceInfo const&, int framesPerBuffer, AudioDevice * sink, unsigned downSampleFactor, AudioDevice::Channel = AudioDevice::Mono);
|
||||
Q_SLOT void suspend ();
|
||||
Q_SLOT void resume ();
|
||||
Q_SLOT void stop ();
|
||||
|
||||
Q_SIGNAL void error (QString message) const;
|
||||
|
Loading…
Reference in New Issue
Block a user