1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-04 16:01:14 -05:00

NFM demod: added display of channel power in dB. Changed minus radio button for a iconified toggle button

This commit is contained in:
f4exb 2015-10-04 06:26:06 +02:00
parent f1cd4bf992
commit 438df2975e
7 changed files with 350 additions and 264 deletions

View File

@ -38,6 +38,9 @@ public:
MagSquaredAGC(int historySize, Real R); MagSquaredAGC(int historySize, Real R);
virtual ~MagSquaredAGC(); virtual ~MagSquaredAGC();
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
Real getMagSq() const { return m_magsq; }
private:
Real m_magsq;
}; };
class MagAGC : public AGC class MagAGC : public AGC
@ -47,6 +50,9 @@ public:
MagAGC(int historySize, Real R); MagAGC(int historySize, Real R);
virtual ~MagAGC(); virtual ~MagAGC();
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
Real getMagSq() const { return m_magsq; }
private:
Real m_magsq;
}; };
class AlphaAGC : public AGC class AlphaAGC : public AGC
@ -58,8 +64,10 @@ public:
virtual ~AlphaAGC(); virtual ~AlphaAGC();
void resize(int historySize, Real R, Real alpha); void resize(int historySize, Real R, Real alpha);
virtual void feed(Complex& ci); virtual void feed(Complex& ci);
Real getMagSq() const { return m_magsq; }
private: private:
Real m_alpha; Real m_alpha;
Real m_magsq;
bool m_squelchOpen; bool m_squelchOpen;
}; };

View File

@ -55,6 +55,7 @@ NFMDemod::NFMDemod() :
m_agcLevel = 1.0; m_agcLevel = 1.0;
m_AGC.resize(240, m_agcLevel); m_AGC.resize(240, m_agcLevel);
m_magsq = 0;
m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution
m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 4000 Hz span, 250us, 100ms attack m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 4000 Hz span, 250us, 100ms attack
@ -134,6 +135,7 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
//ci *= (m_agcLevel / m_AGC.getValue()); //ci *= (m_agcLevel / m_AGC.getValue());
m_AGC.feed(ci); m_AGC.feed(ci);
m_magsq = m_AGC.getMagSq();
// demod // demod
/* /*

View File

@ -64,6 +64,8 @@ public:
m_ctcssIndexSelected = selectedCtcssIndex; m_ctcssIndexSelected = selectedCtcssIndex;
} }
Real getMagSq() const { return m_magsq; }
private: private:
class MsgConfigureNFMDemod : public Message { class MsgConfigureNFMDemod : public Message {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
@ -163,6 +165,7 @@ private:
AFSquelch m_afSquelch; AFSquelch m_afSquelch;
Real m_agcLevel; // AGC will aim to this level Real m_agcLevel; // AGC will aim to this level
Real m_agcFloor; // AGC will not go below this level Real m_agcFloor; // AGC will not go below this level
Real m_magsq;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint m_audioBufferFill; uint m_audioBufferFill;

View File

@ -10,8 +10,10 @@
#include "gui/glspectrum.h" #include "gui/glspectrum.h"
#include "plugin/pluginapi.h" #include "plugin/pluginapi.h"
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "util/db.h"
#include "gui/basicchannelsettingswidget.h" #include "gui/basicchannelsettingswidget.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "mainwindow.h"
const int NFMDemodGUI::m_rfBW[] = { const int NFMDemodGUI::m_rfBW[] = {
5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000 5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000
@ -143,7 +145,7 @@ void NFMDemodGUI::viewChanged()
applySettings(); applySettings();
} }
void NFMDemodGUI::on_deltaMinus_clicked(bool minus) void NFMDemodGUI::on_deltaMinus_toggled(bool minus)
{ {
int deltaFrequency = m_channelMarker.getCenterFrequency(); int deltaFrequency = m_channelMarker.getCenterFrequency();
bool minusDelta = (deltaFrequency < 0); bool minusDelta = (deltaFrequency < 0);
@ -229,7 +231,8 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
m_pluginAPI(pluginAPI), m_pluginAPI(pluginAPI),
m_channelMarker(this), m_channelMarker(this),
m_basicSettingsShown(false), m_basicSettingsShown(false),
m_doApplySettings(true) m_doApplySettings(true),
m_channelPowerDbAvg(20,0)
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
@ -239,6 +242,8 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
m_nfmDemod = new NFMDemod(); m_nfmDemod = new NFMDemod();
m_nfmDemod->registerGUI(this); m_nfmDemod->registerGUI(this);
connect(&m_pluginAPI->getMainWindow()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
int ctcss_nbTones; int ctcss_nbTones;
const Real *ctcss_tones = m_nfmDemod->getCtcssToneSet(ctcss_nbTones); const Real *ctcss_tones = m_nfmDemod->getCtcssToneSet(ctcss_nbTones);
@ -334,3 +339,9 @@ void NFMDemodGUI::blockApplySettings(bool block)
m_doApplySettings = !block; m_doApplySettings = !block;
} }
void NFMDemodGUI::tick()
{
Real powDb = CalcDb::dbPower(m_nfmDemod->getMagSq());
m_channelPowerDbAvg.feed(powDb);
ui->channelPower->setText(QString::number(m_channelPowerDbAvg.average(), 'f', 1));
}

View File

@ -5,6 +5,7 @@
#include "plugin/plugingui.h" #include "plugin/plugingui.h"
#include "dsp/dsptypes.h" #include "dsp/dsptypes.h"
#include "dsp/channelmarker.h" #include "dsp/channelmarker.h"
#include "dsp/movingaverage.h"
class PluginAPI; class PluginAPI;
@ -38,7 +39,7 @@ public:
private slots: private slots:
void viewChanged(); void viewChanged();
void on_deltaFrequency_changed(quint64 value); void on_deltaFrequency_changed(quint64 value);
void on_deltaMinus_clicked(bool minus); void on_deltaMinus_toggled(bool minus);
void on_rfBW_valueChanged(int value); void on_rfBW_valueChanged(int value);
void on_afBW_valueChanged(int value); void on_afBW_valueChanged(int value);
void on_volume_valueChanged(int value); void on_volume_valueChanged(int value);
@ -47,6 +48,7 @@ private slots:
void on_ctcssOn_toggled(bool checked); void on_ctcssOn_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDoubleClicked(); void onMenuDoubleClicked();
void tick();
private: private:
Ui::NFMDemodGUI* ui; Ui::NFMDemodGUI* ui;
@ -59,6 +61,7 @@ private:
Channelizer* m_channelizer; Channelizer* m_channelizer;
NFMDemod* m_nfmDemod; NFMDemod* m_nfmDemod;
bool m_ctcssOn; bool m_ctcssOn;
MovingAverage<Real> m_channelPowerDbAvg;
static const int m_rfBW[]; static const int m_rfBW[];

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>263</width> <width>167</width>
<height>151</height> <height>433</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,14 +18,17 @@
<rect> <rect>
<x>6</x> <x>6</x>
<y>35</y> <y>35</y>
<width>251</width> <width>122</width>
<height>111</height> <height>395</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Settings</string> <string>Settings</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin"> <property name="leftMargin">
<number>2</number> <number>2</number>
</property> </property>
@ -38,226 +41,25 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>2</number> <number>2</number>
</property> </property>
<property name="spacing">
<number>3</number>
</property>
<item row="5" column="4">
<layout class="QHBoxLayout" name="CTCSSblock">
<item> <item>
<widget class="QCheckBox" name="ctcssOn"> <layout class="QHBoxLayout" name="DeltaFrequencyLayout">
<property name="toolTip"> <item>
<string>Activate CTCSS</string> <widget class="QToolButton" name="deltaMinus">
</property>
<property name="text"> <property name="text">
<string/> <string>...</string>
</property>
<property name="icon">
<iconset>
<selectedoff>:/plus.png</selectedoff>
<selectedon>:/minus.png</selectedon>
</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="ctcss">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Set CTCSS Frequency</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="4">
<widget class="QSlider" name="volume">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSlider" name="rfBW">
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>4</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="deltaMinus">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Minus</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="squelchLabel">
<property name="text">
<string>Squelch</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="afLabel">
<property name="text">
<string>AF BW</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rfBWLabel">
<property name="text">
<string>RF BW</string>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSlider" name="squelch">
<property name="toolTip">
<string>Threshold min/max in dB</string>
</property>
<property name="minimum">
<number>-200</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>-150</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="volumeLabel">
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="rfBWText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>12.5 k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QLabel" name="afBWText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>3 k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSlider" name="afBW">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="6">
<widget class="QLabel" name="squelchText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-15.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="QLabel" name="volumeText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>2.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="deltaUnits">
<property name="text">
<string>Hz</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="ctcssLabel">
<property name="text">
<string>CTCSS</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="ValueDial" name="deltaFrequency" native="true"> <widget class="ValueDial" name="deltaFrequency" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum"> <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
@ -288,7 +90,253 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="6"> <item>
<widget class="QLabel" name="deltaUnits">
<property name="text">
<string>Hz </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="channelPower">
<property name="toolTip">
<string>Channel power</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>0.0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="channelPowerUnits">
<property name="text">
<string> dB</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="rfBWLayout">
<item>
<widget class="QLabel" name="rfBWLabel">
<property name="text">
<string>RF BW</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="rfBW">
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>4</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rfBWText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>12.5 k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="afBWLayout">
<item>
<widget class="QLabel" name="afLabel">
<property name="text">
<string>AF BW</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="afBW">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="afBWText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>3 k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="volumeLayout">
<item>
<widget class="QLabel" name="volumeLabel">
<property name="text">
<string>Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="volume">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="volumeText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>2.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="squelchLayout">
<item>
<widget class="QLabel" name="squelchLabel">
<property name="text">
<string>Squelch</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="squelch">
<property name="toolTip">
<string>Threshold min/max in dB</string>
</property>
<property name="minimum">
<number>-200</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>-150</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="squelchText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-15.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="ctcssLayout">
<item>
<widget class="QLabel" name="ctcssLabel">
<property name="text">
<string>CTCSS</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="CTCSSblock">
<item>
<widget class="QCheckBox" name="ctcssOn">
<property name="toolTip">
<string>Activate CTCSS</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="ctcss">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Set CTCSS Frequency</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="ctcssText"> <widget class="QLabel" name="ctcssText">
<property name="toolTip"> <property name="toolTip">
<string>CTCSS detected</string> <string>CTCSS detected</string>
@ -302,6 +350,8 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
</layout>
</widget> </widget>
</widget> </widget>
<customwidgets> <customwidgets>
@ -318,6 +368,8 @@
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources>
<include location="../../../sdrbase/resources/res.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -46,11 +46,13 @@ Real AGC::getAverage()
} }
MagSquaredAGC::MagSquaredAGC() : MagSquaredAGC::MagSquaredAGC() :
AGC() AGC(),
m_magsq(0.0)
{} {}
MagSquaredAGC::MagSquaredAGC(int historySize, Real R) : MagSquaredAGC::MagSquaredAGC(int historySize, Real R) :
AGC(historySize, R) AGC(historySize, R),
m_magsq(0.0)
{} {}
MagSquaredAGC::~MagSquaredAGC() MagSquaredAGC::~MagSquaredAGC()
@ -58,19 +60,21 @@ MagSquaredAGC::~MagSquaredAGC()
void MagSquaredAGC::feed(Complex& ci) void MagSquaredAGC::feed(Complex& ci)
{ {
Real magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag();
m_moving_average.feed(magsq); m_moving_average.feed(m_magsq);
m_u0 = m_R / m_moving_average.average(); m_u0 = m_R / m_moving_average.average();
ci *= m_u0; ci *= m_u0;
} }
MagAGC::MagAGC() : MagAGC::MagAGC() :
AGC() AGC(),
m_magsq(0.0)
{} {}
MagAGC::MagAGC(int historySize, Real R) : MagAGC::MagAGC(int historySize, Real R) :
AGC(historySize, R) AGC(historySize, R),
m_magsq(0.0)
{} {}
MagAGC::~MagAGC() MagAGC::~MagAGC()
@ -78,8 +82,8 @@ MagAGC::~MagAGC()
void MagAGC::feed(Complex& ci) void MagAGC::feed(Complex& ci)
{ {
Real mag = sqrt(ci.real()*ci.real() + ci.imag()*ci.imag()); m_magsq = sqrt(ci.real()*ci.real() + ci.imag()*ci.imag());
m_moving_average.feed(mag); m_moving_average.feed(m_magsq);
m_u0 = m_R / m_moving_average.average(); m_u0 = m_R / m_moving_average.average();
ci *= m_u0; ci *= m_u0;
} }
@ -88,12 +92,14 @@ void MagAGC::feed(Complex& ci)
AlphaAGC::AlphaAGC() : AlphaAGC::AlphaAGC() :
AGC(), AGC(),
m_alpha(0.5), m_alpha(0.5),
m_magsq(0.0),
m_squelchOpen(true) m_squelchOpen(true)
{} {}
AlphaAGC::AlphaAGC(int historySize, Real R) : AlphaAGC::AlphaAGC(int historySize, Real R) :
AGC(historySize, R), AGC(historySize, R),
m_alpha(0.5), m_alpha(0.5),
m_magsq(0.0),
m_squelchOpen(true) m_squelchOpen(true)
{} {}
@ -101,6 +107,7 @@ AlphaAGC::AlphaAGC(int historySize, Real R) :
AlphaAGC::AlphaAGC(int historySize, Real R, Real alpha) : AlphaAGC::AlphaAGC(int historySize, Real R, Real alpha) :
AGC(historySize, R), AGC(historySize, R),
m_alpha(alpha), m_alpha(alpha),
m_magsq(0.0),
m_squelchOpen(true) m_squelchOpen(true)
{} {}
@ -117,16 +124,16 @@ void AlphaAGC::resize(int historySize, Real R, Real alpha)
void AlphaAGC::feed(Complex& ci) void AlphaAGC::feed(Complex& ci)
{ {
Real magsq = ci.real()*ci.real() + ci.imag()*ci.imag(); m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag();
if (m_squelchOpen && (magsq)) if (m_squelchOpen && (m_magsq))
{ {
m_moving_average.feed(m_moving_average.average() - m_alpha*(m_moving_average.average() - magsq)); m_moving_average.feed(m_moving_average.average() - m_alpha*(m_moving_average.average() - m_magsq));
} }
else else
{ {
//m_squelchOpen = true; //m_squelchOpen = true;
m_moving_average.feed(magsq); m_moving_average.feed(m_magsq);
} }
ci *= m_u0; ci *= m_u0;
} }