From cd347bca4ff1756ecdb4f1bbeee4bb6001393a1e Mon Sep 17 00:00:00 2001 From: f4exb Date: Fri, 28 Oct 2016 05:08:53 +0200 Subject: [PATCH] Allow interpolation in AM demodulator i.e. input sample rate lower than audio rate --- plugins/channelrx/demodam/amdemod.cpp | 82 +++++---------------------- plugins/channelrx/demodam/amdemod.h | 70 +++++++++++++++++++++++ 2 files changed, 85 insertions(+), 67 deletions(-) diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp index 0cbced721..76cb810dc 100644 --- a/plugins/channelrx/demodam/amdemod.cpp +++ b/plugins/channelrx/demodam/amdemod.cpp @@ -77,76 +77,24 @@ void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector Complex c(it->real(), it->imag()); c *= m_nco.nextIQ(); - if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) + if (m_interpolatorDistance < 1.0f) // interpolate { - Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); - magsq /= (1<<30); - m_movingAverage.feed(magsq); - m_magsq = m_movingAverage.average(); + processOneSample(ci); - if (m_magsq >= m_squelchLevel) - { - if (m_squelchCount <= m_running.m_audioSampleRate / 10) - { - m_squelchCount++; - } - } - else - { - if (m_squelchCount > 1) - { - m_squelchCount -= 2; - } - } + while (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) + { + processOneSample(ci); + } - qint16 sample; - - if ((m_squelchCount >= m_running.m_audioSampleRate / 20) && !m_running.m_audioMute) - { - Real demod = sqrt(magsq); - - demod = m_lowpass.filter(demod); - - if (demod < -1) - { - demod = -1; - } - else if (demod > 1) - { - demod = 1; - } - - m_volumeAGC.feed(demod); - - Real attack = (m_squelchCount - (m_running.m_audioSampleRate / 20)) / (Real) (m_running.m_audioSampleRate / 20); - demod *= ((0.003 * attack) / m_volumeAGC.getValue()); - demod *= m_running.m_volume; - sample = demod * 32700 * 16; - m_squelchOpen = true; - } - else - { - sample = 0; - m_squelchOpen = false; - } - - m_audioBuffer[m_audioBufferFill].l = sample; - m_audioBuffer[m_audioBufferFill].r = sample; - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10); - - if (res != m_audioBufferFill) - { - qDebug("AMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill); - } - - m_audioBufferFill = 0; - } - - m_interpolatorDistanceRemain += m_interpolatorDistance; + m_interpolatorDistanceRemain += m_interpolatorDistance; + } + else // decimate + { + if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) + { + processOneSample(ci); + m_interpolatorDistanceRemain += m_interpolatorDistance; + } } } diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h index ccc2cfc35..3f634ee60 100644 --- a/plugins/channelrx/demodam/amdemod.h +++ b/plugins/channelrx/demodam/amdemod.h @@ -134,6 +134,76 @@ private: QMutex m_settingsMutex; void apply(); + + void processOneSample(Complex &ci) + { + Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); + magsq /= (1<<30); + m_movingAverage.feed(magsq); + m_magsq = m_movingAverage.average(); + + if (m_magsq >= m_squelchLevel) + { + if (m_squelchCount <= m_running.m_audioSampleRate / 10) + { + m_squelchCount++; + } + } + else + { + if (m_squelchCount > 1) + { + m_squelchCount -= 2; + } + } + + qint16 sample; + + if ((m_squelchCount >= m_running.m_audioSampleRate / 20) && !m_running.m_audioMute) + { + Real demod = sqrt(magsq); + + demod = m_lowpass.filter(demod); + + if (demod < -1) + { + demod = -1; + } + else if (demod > 1) + { + demod = 1; + } + + m_volumeAGC.feed(demod); + + Real attack = (m_squelchCount - (m_running.m_audioSampleRate / 20)) / (Real) (m_running.m_audioSampleRate / 20); + demod *= ((0.003 * attack) / m_volumeAGC.getValue()); + demod *= m_running.m_volume; + sample = demod * 32700 * 16; + m_squelchOpen = true; + } + else + { + sample = 0; + m_squelchOpen = false; + } + + m_audioBuffer[m_audioBufferFill].l = sample; + m_audioBuffer[m_audioBufferFill].r = sample; + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10); + + if (res != m_audioBufferFill) + { + qDebug("AMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill); + } + + m_audioBufferFill = 0; + } + } }; #endif // INCLUDE_AMDEMOD_H