From e7215b54da19d5017dc73ddb6ed2e57346acecd0 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 28 May 2019 18:36:18 +0200 Subject: [PATCH] SSB demod: implemented interpolator for audio --- plugins/channelrx/demodssb/ssbdemod.cpp | 208 ++++++++++++------------ plugins/channelrx/demodssb/ssbdemod.h | 2 + 2 files changed, 110 insertions(+), 100 deletions(-) diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index b76a6dd79..22681d24e 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -157,124 +157,133 @@ void SSBDemod::configure(MessageQueue* messageQueue, void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { (void) positiveOnly; - Complex ci; - fftfilt::cmplx *sideband; - int n_out; - + Complex ci; m_settingsMutex.lock(); - int decim = 1<<(m_spanLog2 - 1); - unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) - for(SampleVector::const_iterator it = begin; it < end; ++it) { Complex c(it->real(), it->imag()); c *= m_nco.nextIQ(); - if(m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) - { - if (m_dsb) - { - n_out = DSBFilter->runDSB(ci, &sideband); - } - else - { - n_out = SSBFilter->runSSB(ci, &sideband, m_usb); - } + if (m_interpolatorDistance < 1.0f) // interpolate + { + while (!m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) + { + processOneSample(ci); + m_interpolatorDistanceRemain += m_interpolatorDistance; + } + } + else + { + if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) + { + processOneSample(ci); + m_interpolatorDistanceRemain += m_interpolatorDistance; + } + } + } - m_interpolatorDistanceRemain += m_interpolatorDistance; - } - else - { - n_out = 0; - } + m_settingsMutex.unlock(); +} - for (int i = 0; i < n_out; i++) - { - // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display - // smart decimation with bit gain using float arithmetic (23 bits significand) +void SSBDemod::processOneSample(Complex &ci) +{ + fftfilt::cmplx *sideband; + int n_out = 0; + int decim = 1<<(m_spanLog2 - 1); + unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) - m_sum += sideband[i]; + if (m_dsb) { + n_out = DSBFilter->runDSB(ci, &sideband); + } else { + n_out = SSBFilter->runSSB(ci, &sideband, m_usb); + } - if (!(m_undersampleCount++ & decim_mask)) - { - Real avgr = m_sum.real() / decim; - Real avgi = m_sum.imag() / decim; - m_magsq = (avgr * avgr + avgi * avgi) / (SDR_RX_SCALED*SDR_RX_SCALED); + for (int i = 0; i < n_out; i++) + { + // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display + // smart decimation with bit gain using float arithmetic (23 bits significand) - m_magsqSum += m_magsq; + m_sum += sideband[i]; - if (m_magsq > m_magsqPeak) + if (!(m_undersampleCount++ & decim_mask)) + { + Real avgr = m_sum.real() / decim; + Real avgi = m_sum.imag() / decim; + m_magsq = (avgr * avgr + avgi * avgi) / (SDR_RX_SCALED*SDR_RX_SCALED); + + m_magsqSum += m_magsq; + + if (m_magsq > m_magsqPeak) + { + m_magsqPeak = m_magsq; + } + + m_magsqCount++; + + if (!m_dsb & !m_usb) + { // invert spectrum for LSB + m_sampleBuffer.push_back(Sample(avgi, avgr)); + } + else + { + m_sampleBuffer.push_back(Sample(avgr, avgi)); + } + + m_sum.real(0.0); + m_sum.imag(0.0); + } + + float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 10.0; // 10.0 for 3276.8, 1.0 for 327.68 + fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); + m_audioActive = delayedSample.real() != 0.0; + m_squelchDelayLine.write(sideband[i]*agcVal); + + if (m_audioMute) + { + m_audioBuffer[m_audioBufferFill].r = 0; + m_audioBuffer[m_audioBufferFill].l = 0; + } + else + { + fftfilt::cmplx z = delayedSample * m_agc.getStepValue(); + + if (m_audioBinaual) + { + if (m_audioFlipChannels) { - m_magsqPeak = m_magsq; + m_audioBuffer[m_audioBufferFill].r = (qint16)(z.imag() * m_volume); + m_audioBuffer[m_audioBufferFill].l = (qint16)(z.real() * m_volume); } + else + { + m_audioBuffer[m_audioBufferFill].r = (qint16)(z.real() * m_volume); + m_audioBuffer[m_audioBufferFill].l = (qint16)(z.imag() * m_volume); + } + } + else + { + Real demod = (z.real() + z.imag()) * 0.7; + qint16 sample = (qint16)(demod * m_volume); + m_audioBuffer[m_audioBufferFill].l = sample; + m_audioBuffer[m_audioBufferFill].r = sample; + } + } - m_magsqCount++; + ++m_audioBufferFill; - if (!m_dsb & !m_usb) - { // invert spectrum for LSB - m_sampleBuffer.push_back(Sample(avgi, avgr)); - } - else - { - m_sampleBuffer.push_back(Sample(avgr, avgi)); - } + if (m_audioBufferFill >= m_audioBuffer.size()) + { + uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); - m_sum.real(0.0); - m_sum.imag(0.0); - } + if (res != m_audioBufferFill) + { + qDebug("SSBDemod::feed: %u/%u samples written", res, m_audioBufferFill); + } - float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 10.0; // 10.0 for 3276.8, 1.0 for 327.68 - fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); - m_audioActive = delayedSample.real() != 0.0; - m_squelchDelayLine.write(sideband[i]*agcVal); - - if (m_audioMute) - { - m_audioBuffer[m_audioBufferFill].r = 0; - m_audioBuffer[m_audioBufferFill].l = 0; - } - else - { - fftfilt::cmplx z = delayedSample * m_agc.getStepValue(); - - if (m_audioBinaual) - { - if (m_audioFlipChannels) - { - m_audioBuffer[m_audioBufferFill].r = (qint16)(z.imag() * m_volume); - m_audioBuffer[m_audioBufferFill].l = (qint16)(z.real() * m_volume); - } - else - { - m_audioBuffer[m_audioBufferFill].r = (qint16)(z.real() * m_volume); - m_audioBuffer[m_audioBufferFill].l = (qint16)(z.imag() * m_volume); - } - } - else - { - Real demod = (z.real() + z.imag()) * 0.7; - qint16 sample = (qint16)(demod * m_volume); - 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); - - if (res != m_audioBufferFill) - { - qDebug("SSBDemod::feed: %u/%u samples written", res, m_audioBufferFill); - } - - m_audioBufferFill = 0; - } - } - } + m_audioBufferFill = 0; + } + } uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); @@ -292,7 +301,6 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_sampleBuffer.clear(); - m_settingsMutex.unlock(); } void SSBDemod::start() diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index 873051c2f..86e96db30 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -338,6 +338,8 @@ private: void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiReverseSendSettings(QList& channelSettingsKeys, const SSBDemodSettings& settings, bool force); + void processOneSample(Complex &ci); + private slots: void networkManagerFinished(QNetworkReply *reply); };