From 96b72667b50dfbb33f087f3ef89314d99b4632f7 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 27 Feb 2019 13:57:38 +0100 Subject: [PATCH] FreeDV demod: collect some statistics --- plugins/channelrx/demodfreedv/freedvdemod.cpp | 57 ++++++++++++++++++- plugins/channelrx/demodfreedv/freedvdemod.h | 20 +++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/plugins/channelrx/demodfreedv/freedvdemod.cpp b/plugins/channelrx/demodfreedv/freedvdemod.cpp index 18790bb36..97cd0bca7 100644 --- a/plugins/channelrx/demodfreedv/freedvdemod.cpp +++ b/plugins/channelrx/demodfreedv/freedvdemod.cpp @@ -46,6 +46,54 @@ MESSAGE_CLASS_DEFINITION(FreeDVDemod::MsgConfigureChannelizer, Message) const QString FreeDVDemod::m_channelIdURI = "sdrangel.channel.freedvdemod"; const QString FreeDVDemod::m_channelId = "FreeDVDemod"; +FreeDVDemod::FreeDVStats::FreeDVStats() +{ + init(); +} + +void FreeDVDemod::FreeDVStats::init() +{ + m_sync = 0; + m_snrEst = -20; + m_clockOffset = 0; + m_freqOffset = 0; + m_syncMetric = 0; + m_totalBitErrors = 0; + m_lastTotalBitErrors = 0; + m_ber = 0; + m_frameCount = 0; + m_berFrameCount = 0; + m_fps = 1; +} + +void FreeDVDemod::FreeDVStats::collect(struct freedv *freeDV) +{ + struct MODEM_STATS stats; + + freedv_get_modem_extended_stats(freeDV, &stats); + m_totalBitErrors = freedv_get_total_bit_errors(freeDV); + m_clockOffset = stats.clock_offset; + m_freqOffset = stats.foff; + m_syncMetric = stats.sync_metric; + m_sync = stats.sync; + m_snrEst = stats.snr_est; + + if (m_berFrameCount >= m_fps) + { + m_ber = m_totalBitErrors - m_lastTotalBitErrors; + m_ber = m_ber < 0 ? 0 : m_ber; + m_berFrameCount = 0; + m_lastTotalBitErrors = m_totalBitErrors; + } + + m_berFrameCount++; + m_frameCount++; + + qDebug("FreeDVStats::collect: demod sync: %d sync metric: %f demod snr: %3.2f dB BER: %d clock offset: %f freq offset: %f", + m_sync, m_syncMetric, m_snrEst, m_ber, m_clockOffset, m_freqOffset); + +} + FreeDVDemod::FreeDVDemod(DeviceSourceAPI *deviceAPI) : ChannelSinkAPI(m_channelIdURI), m_deviceAPI(deviceAPI), @@ -324,6 +372,7 @@ void FreeDVDemod::pushSampleToDV(int16_t sample) if (m_iModem == m_nin) { int nout = freedv_rx(m_freeDV, m_speechOut, m_modIn); + m_freeDVStats.collect(m_freeDV); for (int i = 0; i < nout; i++) { @@ -494,6 +543,11 @@ void FreeDVDemod::applyFreeDVMode(FreeDVDemodSettings::FreeDVMode mode) int nMaxModemSamples = freedv_get_n_max_modem_samples(m_freeDV); int Fs = freedv_get_modem_sample_rate(m_freeDV); int Rs = freedv_get_modem_symbol_rate(m_freeDV); + m_freeDVStats.init(); + + if (m_nin > 0) { + m_freeDVStats.m_fps = m_modemSampleRate / m_nin; + } if (nSpeechSamples != m_nSpeechSamples) { @@ -526,7 +580,8 @@ void FreeDVDemod::applyFreeDVMode(FreeDVDemodSettings::FreeDVMode mode) << " Rs: " << Rs << " m_nSpeechSamples: " << m_nSpeechSamples << " m_nMaxModemSamples: " << m_nMaxModemSamples - << " m_nin: " << m_nin; + << " m_nin: " << m_nin + << " FPS: " << m_freeDVStats.m_fps; } m_settingsMutex.unlock(); diff --git a/plugins/channelrx/demodfreedv/freedvdemod.h b/plugins/channelrx/demodfreedv/freedvdemod.h index 2b3f1dbae..ae2f7049d 100644 --- a/plugins/channelrx/demodfreedv/freedvdemod.h +++ b/plugins/channelrx/demodfreedv/freedvdemod.h @@ -177,6 +177,25 @@ private: double m_magsqPeak; }; + struct FreeDVStats + { + FreeDVStats(); + void init(); + void collect(struct freedv *freedv); + + int m_sync; + float m_snrEst; + float m_clockOffset; + float m_freqOffset; + float m_syncMetric; + int m_totalBitErrors; + int m_lastTotalBitErrors; + int m_ber; //!< estimated BER (b/s) + uint32_t m_frameCount; + uint32_t m_berFrameCount; //!< count of frames for BER estimation + uint32_t m_fps; //!< frames per second + }; + class MsgConfigureFreeDVDemodPrivate : public Message { MESSAGE_CLASS_DECLARATION @@ -326,6 +345,7 @@ private: int16_t *m_speechOut; int16_t *m_modIn; AudioResampler m_audioResampler; + FreeDVStats m_freeDVStats; QMutex m_settingsMutex;