mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-29 03:09:14 -05:00
ChanelAnalyzerNG: added PLL option
This commit is contained in:
parent
a3bd35ff27
commit
3ae7cda9be
@ -35,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
|||||||
*/
|
*/
|
||||||
QCoreApplication::setOrganizationName("f4exb");
|
QCoreApplication::setOrganizationName("f4exb");
|
||||||
QCoreApplication::setApplicationName("SDRangel");
|
QCoreApplication::setApplicationName("SDRangel");
|
||||||
QCoreApplication::setApplicationVersion("3.14.6");
|
QCoreApplication::setApplicationVersion("3.14.7");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
qApp->setStyle(QStyleFactory::create("fusion"));
|
qApp->setStyle(QStyleFactory::create("fusion"));
|
||||||
|
@ -57,7 +57,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
|||||||
|
|
||||||
QCoreApplication::setOrganizationName("f4exb");
|
QCoreApplication::setOrganizationName("f4exb");
|
||||||
QCoreApplication::setApplicationName("SDRangelBench");
|
QCoreApplication::setApplicationName("SDRangelBench");
|
||||||
QCoreApplication::setApplicationVersion("3.14.6");
|
QCoreApplication::setApplicationVersion("3.14.7");
|
||||||
|
|
||||||
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||||
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
||||||
|
@ -56,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
|||||||
|
|
||||||
QCoreApplication::setOrganizationName("f4exb");
|
QCoreApplication::setOrganizationName("f4exb");
|
||||||
QCoreApplication::setApplicationName("SDRangelSrv");
|
QCoreApplication::setApplicationName("SDRangelSrv");
|
||||||
QCoreApplication::setApplicationVersion("3.14.6");
|
QCoreApplication::setApplicationVersion("3.14.7");
|
||||||
|
|
||||||
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||||
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
sdrangel (3.14.7-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* ChanelAnalyzerNG: added PLL option
|
||||||
|
|
||||||
|
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 13 May 2018 20:14:18 +0200
|
||||||
|
|
||||||
sdrangel (3.14.6-1) unstable; urgency=medium
|
sdrangel (3.14.6-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Fixed keyboard input for negative values on realtive integer value dials
|
* Fixed keyboard input for negative values on realtive integer value dials
|
||||||
|
@ -35,6 +35,7 @@ const QString ChannelAnalyzerNG::m_channelId = "ChannelAnalyzerNG";
|
|||||||
ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
|
ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
|
||||||
ChannelSinkAPI(m_channelIdURI),
|
ChannelSinkAPI(m_channelIdURI),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
|
m_pll(0,0.05,0.01),
|
||||||
m_sampleSink(0),
|
m_sampleSink(0),
|
||||||
m_settingsMutex(QMutex::Recursive)
|
m_settingsMutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
@ -73,9 +74,10 @@ void ChannelAnalyzerNG::configure(MessageQueue* messageQueue,
|
|||||||
Real Bandwidth,
|
Real Bandwidth,
|
||||||
Real LowCutoff,
|
Real LowCutoff,
|
||||||
int spanLog2,
|
int spanLog2,
|
||||||
bool ssb)
|
bool ssb,
|
||||||
|
bool pll)
|
||||||
{
|
{
|
||||||
Message* cmd = MsgConfigureChannelAnalyzer::create(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb);
|
Message* cmd = MsgConfigureChannelAnalyzer::create(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb, pll);
|
||||||
messageQueue->push(cmd);
|
messageQueue->push(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,13 +167,15 @@ bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
|
|||||||
m_config.m_LowCutoff = cfg.getLoCutoff();
|
m_config.m_LowCutoff = cfg.getLoCutoff();
|
||||||
m_config.m_spanLog2 = cfg.getSpanLog2();
|
m_config.m_spanLog2 = cfg.getSpanLog2();
|
||||||
m_config.m_ssb = cfg.getSSB();
|
m_config.m_ssb = cfg.getSSB();
|
||||||
|
m_config.m_pll = cfg.getPLL();
|
||||||
|
|
||||||
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer:"
|
qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer:"
|
||||||
<< " m_channelSampleRate: " << m_config.m_channelSampleRate
|
<< " m_channelSampleRate: " << m_config.m_channelSampleRate
|
||||||
<< " m_Bandwidth: " << m_config.m_Bandwidth
|
<< " m_Bandwidth: " << m_config.m_Bandwidth
|
||||||
<< " m_LowCutoff: " << m_config.m_LowCutoff
|
<< " m_LowCutoff: " << m_config.m_LowCutoff
|
||||||
<< " m_spanLog2: " << m_config.m_spanLog2
|
<< " m_spanLog2: " << m_config.m_spanLog2
|
||||||
<< " m_ssb: " << m_config.m_ssb;
|
<< " m_ssb: " << m_config.m_ssb
|
||||||
|
<< " m_pll: " << m_config.m_pll;
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
return true;
|
return true;
|
||||||
@ -254,5 +258,6 @@ void ChannelAnalyzerNG::apply(bool force)
|
|||||||
//m_settingsMutex.lock();
|
//m_settingsMutex.lock();
|
||||||
m_running.m_spanLog2 = m_config.m_spanLog2;
|
m_running.m_spanLog2 = m_config.m_spanLog2;
|
||||||
m_running.m_ssb = m_config.m_ssb;
|
m_running.m_ssb = m_config.m_ssb;
|
||||||
|
m_running.m_pll = m_config.m_pll;
|
||||||
//m_settingsMutex.unlock();
|
//m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "dsp/interpolator.h"
|
#include "dsp/interpolator.h"
|
||||||
#include "dsp/ncof.h"
|
#include "dsp/ncof.h"
|
||||||
#include "dsp/fftfilt.h"
|
#include "dsp/fftfilt.h"
|
||||||
|
#include "dsp/phaselock.h"
|
||||||
#include "audio/audiofifo.h"
|
#include "audio/audiofifo.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
|
||||||
@ -45,20 +46,23 @@ public:
|
|||||||
Real getLoCutoff() const { return m_LowCutoff; }
|
Real getLoCutoff() const { return m_LowCutoff; }
|
||||||
int getSpanLog2() const { return m_spanLog2; }
|
int getSpanLog2() const { return m_spanLog2; }
|
||||||
bool getSSB() const { return m_ssb; }
|
bool getSSB() const { return m_ssb; }
|
||||||
|
bool getPLL() const { return m_pll; }
|
||||||
|
|
||||||
static MsgConfigureChannelAnalyzer* create(
|
static MsgConfigureChannelAnalyzer* create(
|
||||||
int channelSampleRate,
|
int channelSampleRate,
|
||||||
Real Bandwidth,
|
Real Bandwidth,
|
||||||
Real LowCutoff,
|
Real LowCutoff,
|
||||||
int spanLog2,
|
int spanLog2,
|
||||||
bool ssb)
|
bool ssb,
|
||||||
|
bool pll)
|
||||||
{
|
{
|
||||||
return new MsgConfigureChannelAnalyzer(
|
return new MsgConfigureChannelAnalyzer(
|
||||||
channelSampleRate,
|
channelSampleRate,
|
||||||
Bandwidth,
|
Bandwidth,
|
||||||
LowCutoff,
|
LowCutoff,
|
||||||
spanLog2,
|
spanLog2,
|
||||||
ssb);
|
ssb,
|
||||||
|
pll);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,19 +71,22 @@ public:
|
|||||||
Real m_LowCutoff;
|
Real m_LowCutoff;
|
||||||
int m_spanLog2;
|
int m_spanLog2;
|
||||||
bool m_ssb;
|
bool m_ssb;
|
||||||
|
bool m_pll;
|
||||||
|
|
||||||
MsgConfigureChannelAnalyzer(
|
MsgConfigureChannelAnalyzer(
|
||||||
int channelSampleRate,
|
int channelSampleRate,
|
||||||
Real Bandwidth,
|
Real Bandwidth,
|
||||||
Real LowCutoff,
|
Real LowCutoff,
|
||||||
int spanLog2,
|
int spanLog2,
|
||||||
bool ssb) :
|
bool ssb,
|
||||||
|
bool pll) :
|
||||||
Message(),
|
Message(),
|
||||||
m_channelSampleRate(channelSampleRate),
|
m_channelSampleRate(channelSampleRate),
|
||||||
m_Bandwidth(Bandwidth),
|
m_Bandwidth(Bandwidth),
|
||||||
m_LowCutoff(LowCutoff),
|
m_LowCutoff(LowCutoff),
|
||||||
m_spanLog2(spanLog2),
|
m_spanLog2(spanLog2),
|
||||||
m_ssb(ssb)
|
m_ssb(ssb),
|
||||||
|
m_pll(pll)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -133,12 +140,14 @@ public:
|
|||||||
Real Bandwidth,
|
Real Bandwidth,
|
||||||
Real LowCutoff,
|
Real LowCutoff,
|
||||||
int spanLog2,
|
int spanLog2,
|
||||||
bool ssb);
|
bool ssb,
|
||||||
|
bool pll);
|
||||||
|
|
||||||
DownChannelizer *getChannelizer() { return m_channelizer; }
|
DownChannelizer *getChannelizer() { return m_channelizer; }
|
||||||
int getInputSampleRate() const { return m_running.m_inputSampleRate; }
|
int getInputSampleRate() const { return m_running.m_inputSampleRate; }
|
||||||
int getChannelSampleRate() const { return m_running.m_channelSampleRate; }
|
int getChannelSampleRate() const { return m_running.m_channelSampleRate; }
|
||||||
double getMagSq() const { return m_magsq; }
|
double getMagSq() const { return m_magsq; }
|
||||||
|
bool isPllLocked() const { return m_running.m_pll && m_pll.locked(); }
|
||||||
|
|
||||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
|
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
|
||||||
virtual void start();
|
virtual void start();
|
||||||
@ -166,6 +175,7 @@ private:
|
|||||||
Real m_LowCutoff;
|
Real m_LowCutoff;
|
||||||
int m_spanLog2;
|
int m_spanLog2;
|
||||||
bool m_ssb;
|
bool m_ssb;
|
||||||
|
bool m_pll;
|
||||||
|
|
||||||
Config() :
|
Config() :
|
||||||
m_frequency(0),
|
m_frequency(0),
|
||||||
@ -174,7 +184,8 @@ private:
|
|||||||
m_Bandwidth(5000),
|
m_Bandwidth(5000),
|
||||||
m_LowCutoff(300),
|
m_LowCutoff(300),
|
||||||
m_spanLog2(3),
|
m_spanLog2(3),
|
||||||
m_ssb(false)
|
m_ssb(false),
|
||||||
|
m_pll(false)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,6 +203,7 @@ private:
|
|||||||
bool m_useInterpolator;
|
bool m_useInterpolator;
|
||||||
|
|
||||||
NCOF m_nco;
|
NCOF m_nco;
|
||||||
|
SimplePhaseLock m_pll;
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
@ -233,6 +245,25 @@ private:
|
|||||||
Real im = m_sum.imag() / SDR_RX_SCALED;
|
Real im = m_sum.imag() / SDR_RX_SCALED;
|
||||||
m_magsq = re*re + im*im;
|
m_magsq = re*re + im*im;
|
||||||
|
|
||||||
|
if (m_running.m_pll)
|
||||||
|
{
|
||||||
|
Real ncopll[2];
|
||||||
|
m_pll.process(re, im, ncopll);
|
||||||
|
|
||||||
|
Real mixI = m_sum.real() * ncopll[0] - m_sum.imag() * ncopll[1];
|
||||||
|
Real mixQ = m_sum.real() * ncopll[1] + m_sum.imag() * ncopll[0];
|
||||||
|
|
||||||
|
if (m_running.m_ssb & !m_usb)
|
||||||
|
{ // invert spectrum for LSB
|
||||||
|
m_sampleBuffer.push_back(Sample(mixQ, mixI));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sampleBuffer.push_back(Sample(mixI, mixQ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (m_running.m_ssb & !m_usb)
|
if (m_running.m_ssb & !m_usb)
|
||||||
{ // invert spectrum for LSB
|
{ // invert spectrum for LSB
|
||||||
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
|
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
|
||||||
@ -241,6 +272,7 @@ private:
|
|||||||
{
|
{
|
||||||
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
|
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_sum = 0;
|
m_sum = 0;
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,12 @@ void ChannelAnalyzerNGGUI::tick()
|
|||||||
double powDb = CalcDb::dbPower(m_channelAnalyzer->getMagSq());
|
double powDb = CalcDb::dbPower(m_channelAnalyzer->getMagSq());
|
||||||
m_channelPowerDbAvg(powDb);
|
m_channelPowerDbAvg(powDb);
|
||||||
ui->channelPower->setText(tr("%1 dB").arg((Real) m_channelPowerDbAvg, 0, 'f', 1));
|
ui->channelPower->setText(tr("%1 dB").arg((Real) m_channelPowerDbAvg, 0, 'f', 1));
|
||||||
|
|
||||||
|
if (m_channelAnalyzer->isPllLocked()) {
|
||||||
|
ui->pll->setStyleSheet("QToolButton { background-color : green; }");
|
||||||
|
} else {
|
||||||
|
ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
||||||
@ -251,6 +257,11 @@ void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked __attribute__((unused)))
|
||||||
|
{
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerNGGUI::on_useRationalDownsampler_toggled(bool checked __attribute__((unused)))
|
void ChannelAnalyzerNGGUI::on_useRationalDownsampler_toggled(bool checked __attribute__((unused)))
|
||||||
{
|
{
|
||||||
setNewFinalRate(m_spanLog2);
|
setNewFinalRate(m_spanLog2);
|
||||||
@ -578,7 +589,8 @@ void ChannelAnalyzerNGGUI::applySettings()
|
|||||||
ui->BW->value() * 100.0,
|
ui->BW->value() * 100.0,
|
||||||
ui->lowCut->value() * 100.0,
|
ui->lowCut->value() * 100.0,
|
||||||
m_spanLog2,
|
m_spanLog2,
|
||||||
ui->ssb->isChecked());
|
ui->ssb->isChecked(),
|
||||||
|
ui->pll->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void on_deltaFrequency_changed(qint64 value);
|
void on_deltaFrequency_changed(qint64 value);
|
||||||
void on_channelSampleRate_changed(quint64 value);
|
void on_channelSampleRate_changed(quint64 value);
|
||||||
|
void on_pll_toggled(bool checked);
|
||||||
void on_useRationalDownsampler_toggled(bool checked);
|
void on_useRationalDownsampler_toggled(bool checked);
|
||||||
void on_BW_valueChanged(int value);
|
void on_BW_valueChanged(int value);
|
||||||
void on_lowCut_valueChanged(int value);
|
void on_lowCut_valueChanged(int value);
|
||||||
|
@ -179,6 +179,24 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="ChannelSamplingLayout">
|
<layout class="QHBoxLayout" name="ChannelSamplingLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="pll">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>PLL lock</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/unlocked.png</normaloff>
|
||||||
|
<normalon>:/locked.png</normalon>:/unlocked.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="ButtonSwitch" name="useRationalDownsampler">
|
<widget class="ButtonSwitch" name="useRationalDownsampler">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
const PluginDescriptor ChannelAnalyzerNGPlugin::m_pluginDescriptor = {
|
const PluginDescriptor ChannelAnalyzerNGPlugin::m_pluginDescriptor = {
|
||||||
QString("Channel Analyzer NG"),
|
QString("Channel Analyzer NG"),
|
||||||
QString("3.14.5"),
|
QString("3.14.7"),
|
||||||
QString("(c) Edouard Griffiths, F4EXB"),
|
QString("(c) Edouard Griffiths, F4EXB"),
|
||||||
QString("https://github.com/f4exb/sdrangel"),
|
QString("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -262,10 +262,34 @@ void PhaseLock::process(const Real& sample_in, Real *samples_out)
|
|||||||
processPhase(samples_out);
|
processPhase(samples_out);
|
||||||
|
|
||||||
// Multiply locked tone with input.
|
// Multiply locked tone with input.
|
||||||
Real x = sample_in;
|
Real phasor_i = m_psin * sample_in;
|
||||||
Real phasor_i = m_psin * x;
|
Real phasor_q = m_pcos * sample_in;
|
||||||
Real phasor_q = m_pcos * x;
|
|
||||||
|
|
||||||
|
// Actual PLL
|
||||||
|
process_phasor(phasor_i, phasor_q);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhaseLock::process(const Real& real_in, const Real& imag_in, Real *samples_out)
|
||||||
|
{
|
||||||
|
m_pps_events.clear();
|
||||||
|
|
||||||
|
// Generate locked pilot tone.
|
||||||
|
m_psin = sin(m_phase);
|
||||||
|
m_pcos = cos(m_phase);
|
||||||
|
|
||||||
|
// Generate output
|
||||||
|
processPhase(samples_out);
|
||||||
|
|
||||||
|
// Multiply locked tone with input.
|
||||||
|
Real phasor_i = m_psin * real_in - m_pcos * imag_in;
|
||||||
|
Real phasor_q = m_pcos * real_in + m_psin * imag_in;
|
||||||
|
|
||||||
|
// Actual PLL
|
||||||
|
process_phasor(phasor_i, phasor_q);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhaseLock::process_phasor(Real& phasor_i, Real& phasor_q)
|
||||||
|
{
|
||||||
// Run IQ phase error through low-pass filter.
|
// Run IQ phase error through low-pass filter.
|
||||||
phasor_i = m_phasor_b0 * phasor_i
|
phasor_i = m_phasor_b0 * phasor_i
|
||||||
- m_phasor_a1 * m_phasor_i1
|
- m_phasor_a1 * m_phasor_i1
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
* This is the in flow version
|
* This is the in flow version
|
||||||
*/
|
*/
|
||||||
void process(const Real& sample_in, Real *samples_out);
|
void process(const Real& sample_in, Real *samples_out);
|
||||||
|
void process(const Real& real_in, const Real& imag_in, Real *samples_out);
|
||||||
|
|
||||||
/** Return true if the phase-locked loop is locked. */
|
/** Return true if the phase-locked loop is locked. */
|
||||||
bool locked() const
|
bool locked() const
|
||||||
@ -111,6 +112,8 @@ private:
|
|||||||
quint64 m_pps_cnt;
|
quint64 m_pps_cnt;
|
||||||
quint64 m_sample_cnt;
|
quint64 m_sample_cnt;
|
||||||
std::vector<PpsEvent> m_pps_events;
|
std::vector<PpsEvent> m_pps_events;
|
||||||
|
|
||||||
|
void process_phasor(Real& phasor_i, Real& phasor_q);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimplePhaseLock : public PhaseLock
|
class SimplePhaseLock : public PhaseLock
|
||||||
|
Loading…
Reference in New Issue
Block a user