From 02e19b687f1bad8e6539d95f78241d465ed5e6b0 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Sat, 8 Aug 2020 17:12:48 +0100 Subject: [PATCH] Status message to report approximate # of dropped Rx audio frames This is a first cut at this to evaluate buffer size adjustments on supported platforms. A final version might limit status bar reports to >1000 dropped frames or similar. --- Audio/soundin.cpp | 18 ++++++++++++++++-- Audio/soundin.h | 6 +++++- main.cpp | 2 +- widgets/mainwindow.cpp | 30 ++++++++++++++++++++++-------- widgets/mainwindow.h | 1 + 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/Audio/soundin.cpp b/Audio/soundin.cpp index e6e8ef783..5589393b9 100644 --- a/Audio/soundin.cpp +++ b/Audio/soundin.cpp @@ -117,9 +117,9 @@ void SoundInput::resume () } } -void SoundInput::handleStateChanged (QAudio::State newState) const +void SoundInput::handleStateChanged (QAudio::State newState) { - // qDebug () << "SoundInput::handleStateChanged: newState:" << newState; + qDebug () << "SoundInput::handleStateChanged: newState:" << newState; switch (newState) { @@ -128,6 +128,7 @@ void SoundInput::handleStateChanged (QAudio::State newState) const break; case QAudio::ActiveState: + reset (false); Q_EMIT status (tr ("Receiving")); break; @@ -154,6 +155,19 @@ void SoundInput::handleStateChanged (QAudio::State newState) const } } +void SoundInput::reset (bool report_dropped_frames) +{ + if (m_stream) + { + if (report_dropped_frames) + { + auto lost_usec = m_stream->elapsedUSecs () - m_stream->processedUSecs () - cummulative_lost_usec_; + Q_EMIT dropped_frames (m_stream->format ().framesForDuration (lost_usec), lost_usec); + } + cummulative_lost_usec_ = m_stream->elapsedUSecs () - m_stream->processedUSecs (); + } +} + void SoundInput::stop() { if (m_stream) diff --git a/Audio/soundin.h b/Audio/soundin.h index 325d5e89d..7e2c71d39 100644 --- a/Audio/soundin.h +++ b/Audio/soundin.h @@ -24,6 +24,7 @@ public: SoundInput (QObject * parent = nullptr) : QObject {parent} , m_sink {nullptr} + , cummulative_lost_usec_ {0} { } @@ -35,18 +36,21 @@ public: Q_SLOT void suspend (); Q_SLOT void resume (); Q_SLOT void stop (); + Q_SLOT void reset (bool report_dropped_frames); Q_SIGNAL void error (QString message) const; Q_SIGNAL void status (QString message) const; + Q_SIGNAL void dropped_frames (qint32 dropped, qint64 usec); private: // used internally - Q_SLOT void handleStateChanged (QAudio::State) const; + Q_SLOT void handleStateChanged (QAudio::State); bool audioError () const; QScopedPointer m_stream; QPointer m_sink; + qint64 cummulative_lost_usec_; }; #endif diff --git a/main.cpp b/main.cpp index 62e85e90f..c167a0396 100644 --- a/main.cpp +++ b/main.cpp @@ -97,7 +97,7 @@ namespace int main(int argc, char *argv[]) { // ### Add timestamps to all debug messages -// qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}"); + qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}"); init_random_seed (); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index c9ee10b8a..6625e8fd9 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -469,9 +469,13 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, 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::reset_audio_input_stream, m_soundInput, &SoundInput::reset); connect (this, &MainWindow::finished, m_soundInput, &SoundInput::stop); connect(m_soundInput, &SoundInput::error, this, &MainWindow::showSoundInError); // connect(m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage); + connect (m_soundInput, &SoundInput::dropped_frames, this, [this] (qint32 dropped_frames, qint64 usec) { + showStatusMessage (tr ("%1 (%2 sec) audio frames dropped").arg (dropped_frames).arg (usec / 1.e6)); + }); connect (&m_audioThread, &QThread::finished, m_soundInput, &QObject::deleteLater); connect (this, &MainWindow::finished, this, &MainWindow::close); @@ -935,12 +939,18 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, connect (&m_wav_future_watcher, &QFutureWatcher::finished, this, &MainWindow::diskDat); connect(&watcher3, SIGNAL(finished()),this,SLOT(fast_decode_done())); - Q_EMIT startAudioInputStream (m_config.audio_input_device () - , m_config.audio_input_buffer_size () - , m_detector, m_downSampleFactor, m_config.audio_input_channel ()); - Q_EMIT initializeAudioOutputStream (m_config.audio_output_device () - , AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2 - , m_config.audio_output_buffer_size ()); + if (!m_config.audio_input_device ().isNull ()) + { + Q_EMIT startAudioInputStream (m_config.audio_input_device () + , m_config.audio_input_buffer_size () + , m_detector, m_downSampleFactor, m_config.audio_input_channel ()); + } + if (!m_config.audio_output_device ().isNull ()) + { + Q_EMIT initializeAudioOutputStream (m_config.audio_output_device () + , AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2 + , m_config.audio_output_buffer_size ()); + } Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT); enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook @@ -1536,6 +1546,10 @@ void MainWindow::dataSink(qint64 frames) if(m_mode!="WSPR") decode(); //Start decoder if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return; + if (!m_diskData) + { + Q_EMIT reset_audio_input_stream (true); // signals dropped samples + } if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST4W")) { //Always save unless "Save None"; may delete later if(m_TRperiod < 60) { @@ -2280,10 +2294,10 @@ bool MainWindow::eventFilter (QObject * object, QEvent * event) void MainWindow::createStatusBar() //createStatusBar { tx_status_label.setAlignment (Qt::AlignHCenter); - tx_status_label.setMinimumSize (QSize {150, 18}); + tx_status_label.setMinimumSize (QSize {100, 18}); tx_status_label.setStyleSheet ("QLabel{color: #000000; background-color: #00ff00}"); tx_status_label.setFrameStyle (QFrame::Panel | QFrame::Sunken); - statusBar()->addWidget (&tx_status_label); + statusBar()->addPermanentWidget (&tx_status_label); config_label.setAlignment (Qt::AlignHCenter); config_label.setMinimumSize (QSize {80, 18}); diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 2f95ac801..a1673ec71 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -346,6 +346,7 @@ private: int TRperiod=60) const; Q_SIGNAL void outAttenuationChanged (qreal) const; Q_SIGNAL void toggleShorthand () const; + Q_SIGNAL void reset_audio_input_stream (bool report_dropped_frames) const; private: void set_mode (QString const& mode);