diff --git a/plugins/channelrx/chanalyzerng/chanalyzerng.h b/plugins/channelrx/chanalyzerng/chanalyzerng.h index 359655859..255597f68 100644 --- a/plugins/channelrx/chanalyzerng/chanalyzerng.h +++ b/plugins/channelrx/chanalyzerng/chanalyzerng.h @@ -1,183 +1,183 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2017 Edouard Griffiths, F4EXB // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDE_CHANALYZERNG_H -#define INCLUDE_CHANALYZERNG_H - -#include -#include -#include - -#include "dsp/interpolator.h" -#include "dsp/ncof.h" -#include "dsp/fftfilt.h" -#include "audio/audiofifo.h" -#include "util/message.h" - -#define ssbFftLen 1024 - -class ChannelAnalyzerNG : public BasebandSampleSink { -public: - ChannelAnalyzerNG(BasebandSampleSink* m_sampleSink); - virtual ~ChannelAnalyzerNG(); - - void configure(MessageQueue* messageQueue, - int channelSampleRate, - Real Bandwidth, - Real LowCutoff, - int spanLog2, - bool ssb); - - int getInputSampleRate() const { return m_running.m_inputSampleRate; } - int getChannelSampleRate() const { return m_running.m_channelSampleRate; } - Real getMagSq() const { return m_magsq; } - - virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); - virtual void start(); - virtual void stop(); - virtual bool handleMessage(const Message& cmd); - -private: - class MsgConfigureChannelAnalyzer : public Message { - MESSAGE_CLASS_DECLARATION - - public: - int getChannelSampleRate() const { return m_channelSampleRate; } - Real getBandwidth() const { return m_Bandwidth; } - Real getLoCutoff() const { return m_LowCutoff; } - int getSpanLog2() const { return m_spanLog2; } - bool getSSB() const { return m_ssb; } - - static MsgConfigureChannelAnalyzer* create( - int channelSampleRate, - Real Bandwidth, - Real LowCutoff, - int spanLog2, - bool ssb) - { - return new MsgConfigureChannelAnalyzer(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb); - } - - private: - int m_channelSampleRate; - Real m_Bandwidth; - Real m_LowCutoff; - int m_spanLog2; - bool m_ssb; - - MsgConfigureChannelAnalyzer( - int channelSampleRate, - Real Bandwidth, - Real LowCutoff, - int spanLog2, - bool ssb) : - Message(), - m_channelSampleRate(channelSampleRate), - m_Bandwidth(Bandwidth), - m_LowCutoff(LowCutoff), - m_spanLog2(spanLog2), - m_ssb(ssb) - { } - }; - - struct Config - { - int m_frequency; - int m_inputSampleRate; - int m_channelSampleRate; - Real m_Bandwidth; - Real m_LowCutoff; - int m_spanLog2; - bool m_ssb; - - Config() : - m_frequency(0), - m_inputSampleRate(96000), - m_channelSampleRate(96000), - m_Bandwidth(5000), - m_LowCutoff(300), - m_spanLog2(3), - m_ssb(false) - {} - }; - - Config m_config; - Config m_running; - - int m_undersampleCount; - fftfilt::cmplx m_sum; - bool m_usb; - Real m_magsq; - bool m_useInterpolator; - - NCOF m_nco; - Interpolator m_interpolator; - Real m_interpolatorDistance; - Real m_interpolatorDistanceRemain; - - fftfilt* SSBFilter; - fftfilt* DSBFilter; - - BasebandSampleSink* m_sampleSink; - SampleVector m_sampleBuffer; - QMutex m_settingsMutex; - - void apply(bool force = false); - - void processOneSample(Complex& c, fftfilt::cmplx *sideband) - { - int n_out; - int decim = 1<runSSB(c, &sideband, m_usb); - } - else - { - n_out = DSBFilter->runDSB(c, &sideband); - } - - 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_sum += sideband[i]; - - if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) - { - m_sum /= decim; - m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30); - - if (m_running.m_ssb & !m_usb) - { // invert spectrum for LSB - //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0)); - m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real())); - } - else - { - //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0)); - m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag())); - } - - m_sum = 0; - } - } - } -}; - -#endif // INCLUDE_CHANALYZERNG_H +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_CHANALYZERNG_H +#define INCLUDE_CHANALYZERNG_H + +#include +#include +#include + +#include "dsp/interpolator.h" +#include "dsp/ncof.h" +#include "dsp/fftfilt.h" +#include "audio/audiofifo.h" +#include "util/message.h" + +#define ssbFftLen 1024 + +class ChannelAnalyzerNG : public BasebandSampleSink { +public: + ChannelAnalyzerNG(BasebandSampleSink* m_sampleSink); + virtual ~ChannelAnalyzerNG(); + + void configure(MessageQueue* messageQueue, + int channelSampleRate, + Real Bandwidth, + Real LowCutoff, + int spanLog2, + bool ssb); + + int getInputSampleRate() const { return m_running.m_inputSampleRate; } + int getChannelSampleRate() const { return m_running.m_channelSampleRate; } + Real getMagSq() const { return m_magsq == 0 ? 1e-10 : m_magsq; } + + virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); + +private: + class MsgConfigureChannelAnalyzer : public Message { + MESSAGE_CLASS_DECLARATION + + public: + int getChannelSampleRate() const { return m_channelSampleRate; } + Real getBandwidth() const { return m_Bandwidth; } + Real getLoCutoff() const { return m_LowCutoff; } + int getSpanLog2() const { return m_spanLog2; } + bool getSSB() const { return m_ssb; } + + static MsgConfigureChannelAnalyzer* create( + int channelSampleRate, + Real Bandwidth, + Real LowCutoff, + int spanLog2, + bool ssb) + { + return new MsgConfigureChannelAnalyzer(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb); + } + + private: + int m_channelSampleRate; + Real m_Bandwidth; + Real m_LowCutoff; + int m_spanLog2; + bool m_ssb; + + MsgConfigureChannelAnalyzer( + int channelSampleRate, + Real Bandwidth, + Real LowCutoff, + int spanLog2, + bool ssb) : + Message(), + m_channelSampleRate(channelSampleRate), + m_Bandwidth(Bandwidth), + m_LowCutoff(LowCutoff), + m_spanLog2(spanLog2), + m_ssb(ssb) + { } + }; + + struct Config + { + int m_frequency; + int m_inputSampleRate; + int m_channelSampleRate; + Real m_Bandwidth; + Real m_LowCutoff; + int m_spanLog2; + bool m_ssb; + + Config() : + m_frequency(0), + m_inputSampleRate(96000), + m_channelSampleRate(96000), + m_Bandwidth(5000), + m_LowCutoff(300), + m_spanLog2(3), + m_ssb(false) + {} + }; + + Config m_config; + Config m_running; + + int m_undersampleCount; + fftfilt::cmplx m_sum; + bool m_usb; + Real m_magsq; + bool m_useInterpolator; + + NCOF m_nco; + Interpolator m_interpolator; + Real m_interpolatorDistance; + Real m_interpolatorDistanceRemain; + + fftfilt* SSBFilter; + fftfilt* DSBFilter; + + BasebandSampleSink* m_sampleSink; + SampleVector m_sampleBuffer; + QMutex m_settingsMutex; + + void apply(bool force = false); + + void processOneSample(Complex& c, fftfilt::cmplx *sideband) + { + int n_out; + int decim = 1<runSSB(c, &sideband, m_usb); + } + else + { + n_out = DSBFilter->runDSB(c, &sideband); + } + + 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_sum += sideband[i]; + + if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) + { + m_sum /= decim; + m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30); + + if (m_running.m_ssb & !m_usb) + { // invert spectrum for LSB + //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0)); + m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real())); + } + else + { + //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0)); + m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag())); + } + + m_sum = 0; + } + } + } +}; + +#endif // INCLUDE_CHANALYZERNG_H diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h index 3f7830a83..193975ecb 100644 --- a/plugins/channelrx/demodam/amdemod.h +++ b/plugins/channelrx/demodam/amdemod.h @@ -46,9 +46,9 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; diff --git a/plugins/channelrx/demodbfm/bfmdemod.h b/plugins/channelrx/demodbfm/bfmdemod.h index cb65fcdcc..e625949a5 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.h +++ b/plugins/channelrx/demodbfm/bfmdemod.h @@ -71,10 +71,10 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; m_magsq = avg; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; diff --git a/plugins/channelrx/demoddsd/dsddemod.h b/plugins/channelrx/demoddsd/dsddemod.h index 62c394e59..d15b105d6 100644 --- a/plugins/channelrx/demoddsd/dsddemod.h +++ b/plugins/channelrx/demoddsd/dsddemod.h @@ -75,15 +75,16 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; m_magsq = avg; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; } + private: class MsgConfigureMyPosition : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index e74a69ae1..577b7668f 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -74,10 +74,10 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; m_magsq = avg; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index bff505959..4bfd65dda 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -53,10 +53,10 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; m_magsq = avg; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; diff --git a/plugins/channelrx/demodwfm/wfmdemod.h b/plugins/channelrx/demodwfm/wfmdemod.h index dff66af64..07ddf02f5 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.h +++ b/plugins/channelrx/demodwfm/wfmdemod.h @@ -55,10 +55,10 @@ public: void getMagSqLevels(Real& avg, Real& peak, int& nbSamples) { - avg = m_magsqSum / m_magsqCount; + avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount; m_magsq = avg; - peak = m_magsqPeak; - nbSamples = m_magsqCount; + peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak; + nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount; m_magsqSum = 0.0f; m_magsqPeak = 0.0f; m_magsqCount = 0; diff --git a/plugins/channeltx/modam/ammod.h b/plugins/channeltx/modam/ammod.h index 14418af98..9c0831598 100644 --- a/plugins/channeltx/modam/ammod.h +++ b/plugins/channeltx/modam/ammod.h @@ -190,7 +190,7 @@ public: virtual void stop(); virtual bool handleMessage(const Message& cmd); - Real getMagSq() const { return m_magsq; } + Real getMagSq() const { return m_magsq == 0.0 ? 1e-10 : m_magsq; } CWKeyer *getCWKeyer() { return &m_cwKeyer; } diff --git a/plugins/channeltx/modnfm/nfmmod.h b/plugins/channeltx/modnfm/nfmmod.h index 4321c16b7..abed3294d 100644 --- a/plugins/channeltx/modnfm/nfmmod.h +++ b/plugins/channeltx/modnfm/nfmmod.h @@ -195,7 +195,7 @@ public: virtual void stop(); virtual bool handleMessage(const Message& cmd); - Real getMagSq() const { return m_magsq; } + Real getMagSq() const { return m_magsq == 0 ? 1e-10 : m_magsq; } CWKeyer *getCWKeyer() { return &m_cwKeyer; } diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h index 2c0a22b38..d0c409185 100644 --- a/plugins/channeltx/modssb/ssbmod.h +++ b/plugins/channeltx/modssb/ssbmod.h @@ -195,7 +195,7 @@ public: virtual void stop(); virtual bool handleMessage(const Message& cmd); - Real getMagSq() const { return m_magsq; } + Real getMagSq() const { return m_magsq == 0 ? 1e-10 : m_magsq; } CWKeyer *getCWKeyer() { return &m_cwKeyer; } diff --git a/plugins/channeltx/modwfm/wfmmod.h b/plugins/channeltx/modwfm/wfmmod.h index 2a68823d6..eb16ea5fe 100644 --- a/plugins/channeltx/modwfm/wfmmod.h +++ b/plugins/channeltx/modwfm/wfmmod.h @@ -192,7 +192,7 @@ public: virtual void stop(); virtual bool handleMessage(const Message& cmd); - Real getMagSq() const { return m_magsq; } + Real getMagSq() const { return m_magsq == 0 ? 1e-10 : m_magsq; } CWKeyer *getCWKeyer() { return &m_cwKeyer; }