mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-09-28 15:56:33 -04:00
ATV Demod: implemented BFU with PLL for single sideband modes
This commit is contained in:
parent
a8adc84e89
commit
303fd3ccc7
@ -126,6 +126,7 @@ set(sdrbase_SOURCES
|
|||||||
sdrbase/dsp/basebandsamplesink.cpp
|
sdrbase/dsp/basebandsamplesink.cpp
|
||||||
sdrbase/dsp/basebandsamplesource.cpp
|
sdrbase/dsp/basebandsamplesource.cpp
|
||||||
sdrbase/dsp/nullsink.cpp
|
sdrbase/dsp/nullsink.cpp
|
||||||
|
sdrbase/dsp/recursivefilters.cpp
|
||||||
sdrbase/dsp/spectrumscopecombovis.cpp
|
sdrbase/dsp/spectrumscopecombovis.cpp
|
||||||
sdrbase/dsp/spectrumscopengcombovis.cpp
|
sdrbase/dsp/spectrumscopengcombovis.cpp
|
||||||
sdrbase/dsp/scopevis.cpp
|
sdrbase/dsp/scopevis.cpp
|
||||||
@ -235,6 +236,7 @@ set(sdrbase_HEADERS
|
|||||||
sdrbase/dsp/phasediscri.h
|
sdrbase/dsp/phasediscri.h
|
||||||
sdrbase/dsp/phaselock.h
|
sdrbase/dsp/phaselock.h
|
||||||
sdrbase/dsp/pidcontroller.h
|
sdrbase/dsp/pidcontroller.h
|
||||||
|
sdrbase/dsp/recursivefilters.h
|
||||||
sdrbase/dsp/samplesinkfifo.h
|
sdrbase/dsp/samplesinkfifo.h
|
||||||
sdrbase/dsp/samplesourcefifo.h
|
sdrbase/dsp/samplesourcefifo.h
|
||||||
sdrbase/dsp/samplesinkfifodoublebuffered.h
|
sdrbase/dsp/samplesinkfifodoublebuffered.h
|
||||||
|
@ -51,6 +51,8 @@ ATVDemod::ATVDemod() :
|
|||||||
m_fltAmpDelta(1.0),
|
m_fltAmpDelta(1.0),
|
||||||
m_fltAmpLineAverage(0.0f),
|
m_fltAmpLineAverage(0.0f),
|
||||||
m_intNumberSamplePerTop(0),
|
m_intNumberSamplePerTop(0),
|
||||||
|
m_bfoPLL(200/1000000, 100/1000000, 0.01),
|
||||||
|
m_bfoFilter(200.0, 1000000.0, 0.9),
|
||||||
m_interpolatorDistanceRemain(0.0f),
|
m_interpolatorDistanceRemain(0.0f),
|
||||||
m_interpolatorDistance(1.0f),
|
m_interpolatorDistance(1.0f),
|
||||||
m_DSBFilter(0),
|
m_DSBFilter(0),
|
||||||
@ -113,14 +115,16 @@ void ATVDemod::configureRF(
|
|||||||
float fltRFBandwidth,
|
float fltRFBandwidth,
|
||||||
float fltRFOppBandwidth,
|
float fltRFOppBandwidth,
|
||||||
bool blnFFTFiltering,
|
bool blnFFTFiltering,
|
||||||
bool blnDecimatorEnable)
|
bool blnDecimatorEnable,
|
||||||
|
float fltBFOFrequency)
|
||||||
{
|
{
|
||||||
Message* msgCmd = MsgConfigureRFATVDemod::create(
|
Message* msgCmd = MsgConfigureRFATVDemod::create(
|
||||||
enmModulation,
|
enmModulation,
|
||||||
fltRFBandwidth,
|
fltRFBandwidth,
|
||||||
fltRFOppBandwidth,
|
fltRFOppBandwidth,
|
||||||
blnFFTFiltering,
|
blnFFTFiltering,
|
||||||
blnDecimatorEnable);
|
blnDecimatorEnable,
|
||||||
|
fltBFOFrequency);
|
||||||
objMessageQueue->push(msgCmd);
|
objMessageQueue->push(msgCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +242,7 @@ void ATVDemod::demod(Complex& c)
|
|||||||
int n_out;
|
int n_out;
|
||||||
fftfilt::cmplx *filtered;
|
fftfilt::cmplx *filtered;
|
||||||
|
|
||||||
n_out = m_DSBFilter->runAsym(c, &filtered, m_objRFRunning.m_enmModulation != ATV_VAML); // all usb except explicitely lsb
|
n_out = m_DSBFilter->runAsym(c, &filtered, m_objRFRunning.m_enmModulation != ATV_LSB); // all usb except explicitely lsb
|
||||||
|
|
||||||
if (n_out > 0)
|
if (n_out > 0)
|
||||||
{
|
{
|
||||||
@ -308,7 +312,7 @@ void ATVDemod::demod(Complex& c)
|
|||||||
m_fltBufferQ[0]=fltNormQ;
|
m_fltBufferQ[0]=fltNormQ;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ((m_objRFRunning.m_enmModulation == ATV_AM) || (m_objRFRunning.m_enmModulation == ATV_VAMU) || (m_objRFRunning.m_enmModulation == ATV_VAML))
|
else if (m_objRFRunning.m_enmModulation == ATV_AM)
|
||||||
{
|
{
|
||||||
//Amplitude AM
|
//Amplitude AM
|
||||||
fltVal = fltNorm;
|
fltVal = fltNorm;
|
||||||
@ -329,6 +333,39 @@ void ATVDemod::demod(Complex& c)
|
|||||||
fltVal -= m_fltAmpMin;
|
fltVal -= m_fltAmpMin;
|
||||||
fltVal /=m_fltAmpDelta;
|
fltVal /=m_fltAmpDelta;
|
||||||
}
|
}
|
||||||
|
else if ((m_objRFRunning.m_enmModulation == ATV_USB) || (m_objRFRunning.m_enmModulation == ATV_LSB))
|
||||||
|
{
|
||||||
|
Real bfoValues[2];
|
||||||
|
float fltFiltered = m_bfoFilter.run(fltI);
|
||||||
|
m_bfoPLL.process(fltFiltered, bfoValues);
|
||||||
|
|
||||||
|
// do the mix
|
||||||
|
|
||||||
|
float mixI = fltI * bfoValues[0] - fltQ * bfoValues[1];
|
||||||
|
float mixQ = fltI * bfoValues[1] + fltQ * bfoValues[0];
|
||||||
|
|
||||||
|
if (m_objRFRunning.m_enmModulation == ATV_USB) {
|
||||||
|
fltVal = (mixI + mixQ);
|
||||||
|
} else {
|
||||||
|
fltVal = (mixI - mixQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
//********** Mini and Maxi Amplitude tracking **********
|
||||||
|
|
||||||
|
if(fltVal<m_fltEffMin)
|
||||||
|
{
|
||||||
|
m_fltEffMin=fltVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fltVal>m_fltEffMax)
|
||||||
|
{
|
||||||
|
m_fltEffMax=fltVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Normalisation
|
||||||
|
fltVal -= m_fltAmpMin;
|
||||||
|
fltVal /=m_fltAmpDelta;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fltVal = 0.0f;
|
fltVal = 0.0f;
|
||||||
@ -560,14 +597,14 @@ bool ATVDemod::handleMessage(const Message& cmd)
|
|||||||
m_objConfig = objCfg.m_objMsgConfig;
|
m_objConfig = objCfg.m_objMsgConfig;
|
||||||
|
|
||||||
qDebug() << "ATVDemod::handleMessage: MsgConfigureATVDemod:"
|
qDebug() << "ATVDemod::handleMessage: MsgConfigureATVDemod:"
|
||||||
<< " m_fltVoltLevelSynchroBlack" << m_objConfig.m_fltVoltLevelSynchroBlack
|
<< " m_fltVoltLevelSynchroBlack:" << m_objConfig.m_fltVoltLevelSynchroBlack
|
||||||
<< " m_fltVoltLevelSynchroTop" << m_objConfig.m_fltVoltLevelSynchroTop
|
<< " m_fltVoltLevelSynchroTop:" << m_objConfig.m_fltVoltLevelSynchroTop
|
||||||
<< " m_fltFramePerS" << m_objConfig.m_fltFramePerS
|
<< " m_fltFramePerS:" << m_objConfig.m_fltFramePerS
|
||||||
<< " m_fltLineDurationUs" << m_objConfig.m_fltLineDurationUs
|
<< " m_fltLineDurationUs:" << m_objConfig.m_fltLineDurationUs
|
||||||
<< " m_fltRatioOfRowsToDisplay" << m_objConfig.m_fltRatioOfRowsToDisplay
|
<< " m_fltRatioOfRowsToDisplay:" << m_objConfig.m_fltRatioOfRowsToDisplay
|
||||||
<< " m_fltTopDurationUs" << m_objConfig.m_fltTopDurationUs
|
<< " m_fltTopDurationUs:" << m_objConfig.m_fltTopDurationUs
|
||||||
<< " m_blnHSync" << m_objConfig.m_blnHSync
|
<< " m_blnHSync:" << m_objConfig.m_blnHSync
|
||||||
<< " m_blnVSync" << m_objConfig.m_blnVSync;
|
<< " m_blnVSync:" << m_objConfig.m_blnVSync;
|
||||||
|
|
||||||
applySettings();
|
applySettings();
|
||||||
|
|
||||||
@ -580,11 +617,12 @@ bool ATVDemod::handleMessage(const Message& cmd)
|
|||||||
m_objRFConfig = objCfg.m_objMsgConfig;
|
m_objRFConfig = objCfg.m_objMsgConfig;
|
||||||
|
|
||||||
qDebug() << "ATVDemod::handleMessage: MsgConfigureRFATVDemod:"
|
qDebug() << "ATVDemod::handleMessage: MsgConfigureRFATVDemod:"
|
||||||
<< " m_enmModulation" << m_objRFConfig.m_enmModulation
|
<< " m_enmModulation:" << m_objRFConfig.m_enmModulation
|
||||||
<< " m_fltRFBandwidth" << m_objRFConfig.m_fltRFBandwidth
|
<< " m_fltRFBandwidth:" << m_objRFConfig.m_fltRFBandwidth
|
||||||
<< " m_fltRFOppBandwidth" << m_objRFConfig.m_fltRFOppBandwidth
|
<< " m_fltRFOppBandwidth:" << m_objRFConfig.m_fltRFOppBandwidth
|
||||||
<< " m_blnFFTFiltering" << m_objRFConfig.m_blnFFTFiltering
|
<< " m_blnFFTFiltering:" << m_objRFConfig.m_blnFFTFiltering
|
||||||
<< " m_blnDecimatorEnable" << m_objRFConfig.m_blndecimatorEnable;
|
<< " m_blnDecimatorEnable:" << m_objRFConfig.m_blndecimatorEnable
|
||||||
|
<< " m_fltBFOFrequency:" << m_objRFConfig.m_fltBFOFrequency;
|
||||||
|
|
||||||
applySettings();
|
applySettings();
|
||||||
|
|
||||||
@ -677,6 +715,14 @@ void ATVDemod::applySettings()
|
|||||||
m_objSettingsMutex.unlock();
|
m_objSettingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((m_objConfigPrivate.m_intTVSampleRate != m_objRunningPrivate.m_intTVSampleRate)
|
||||||
|
|| (m_objRFConfig.m_fltBFOFrequency != m_objRFRunning.m_fltBFOFrequency))
|
||||||
|
{
|
||||||
|
m_bfoPLL.configure(m_objRFConfig.m_fltBFOFrequency / m_objConfigPrivate.m_intTVSampleRate,
|
||||||
|
100.0 / m_objConfigPrivate.m_intTVSampleRate,
|
||||||
|
0.01);
|
||||||
|
m_bfoFilter.setFrequencies(m_objRFConfig.m_fltBFOFrequency, m_objConfigPrivate.m_intTVSampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
m_objRunning = m_objConfig;
|
m_objRunning = m_objConfig;
|
||||||
m_objRFRunning = m_objRFConfig;
|
m_objRFRunning = m_objRFConfig;
|
||||||
@ -692,3 +738,15 @@ int ATVDemod::getEffectiveSampleRate()
|
|||||||
{
|
{
|
||||||
return m_objRFRunning.m_blndecimatorEnable ? m_objRunningPrivate.m_intTVSampleRate : m_objRunning.m_intSampleRate;
|
return m_objRFRunning.m_blndecimatorEnable ? m_objRunningPrivate.m_intTVSampleRate : m_objRunning.m_intSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ATVDemod::getBFOLocked()
|
||||||
|
{
|
||||||
|
if ((m_objRFRunning.m_enmModulation == ATV_USB) || (m_objRFRunning.m_enmModulation == ATV_LSB))
|
||||||
|
{
|
||||||
|
return m_bfoPLL.locked();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "dsp/movingaverage.h"
|
#include "dsp/movingaverage.h"
|
||||||
#include "dsp/fftfilt.h"
|
#include "dsp/fftfilt.h"
|
||||||
#include "dsp/agc.h"
|
#include "dsp/agc.h"
|
||||||
|
#include "dsp/phaselock.h"
|
||||||
|
#include "dsp/recursivefilters.h"
|
||||||
#include "audio/audiofifo.h"
|
#include "audio/audiofifo.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
#include "atvscreen.h"
|
#include "atvscreen.h"
|
||||||
@ -46,8 +48,8 @@ public:
|
|||||||
ATV_FM1, //!< Classical frequency modulation with discriminator #1
|
ATV_FM1, //!< Classical frequency modulation with discriminator #1
|
||||||
ATV_FM2, //!< Classical frequency modulation with discriminator #2
|
ATV_FM2, //!< Classical frequency modulation with discriminator #2
|
||||||
ATV_AM, //!< Classical amplitude modulation
|
ATV_AM, //!< Classical amplitude modulation
|
||||||
ATV_VAMU, //!< AM with vestigial lower side band (main signal is in the upper side)
|
ATV_USB, //!< AM with vestigial lower side band (main signal is in the upper side)
|
||||||
ATV_VAML //!< AM with vestigial upper side band (main signal is in the lower side)
|
ATV_LSB //!< AM with vestigial upper side band (main signal is in the lower side)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ATVConfig
|
struct ATVConfig
|
||||||
@ -84,6 +86,7 @@ public:
|
|||||||
float m_fltRFOppBandwidth;
|
float m_fltRFOppBandwidth;
|
||||||
bool m_blnFFTFiltering;
|
bool m_blnFFTFiltering;
|
||||||
bool m_blndecimatorEnable;
|
bool m_blndecimatorEnable;
|
||||||
|
float m_fltBFOFrequency;
|
||||||
|
|
||||||
ATVRFConfig() :
|
ATVRFConfig() :
|
||||||
m_intFrequencyOffset(0),
|
m_intFrequencyOffset(0),
|
||||||
@ -91,7 +94,8 @@ public:
|
|||||||
m_fltRFBandwidth(0),
|
m_fltRFBandwidth(0),
|
||||||
m_fltRFOppBandwidth(0),
|
m_fltRFOppBandwidth(0),
|
||||||
m_blnFFTFiltering(false),
|
m_blnFFTFiltering(false),
|
||||||
m_blndecimatorEnable(false)
|
m_blndecimatorEnable(false),
|
||||||
|
m_fltBFOFrequency(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -135,7 +139,8 @@ public:
|
|||||||
float fltRFBandwidth,
|
float fltRFBandwidth,
|
||||||
float fltRFOppBandwidth,
|
float fltRFOppBandwidth,
|
||||||
bool blnFFTFiltering,
|
bool blnFFTFiltering,
|
||||||
bool blndecimatorEnable);
|
bool blndecimatorEnable,
|
||||||
|
float fltBFOFrequency);
|
||||||
|
|
||||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
|
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
|
||||||
virtual void start();
|
virtual void start();
|
||||||
@ -146,6 +151,7 @@ public:
|
|||||||
int getSampleRate();
|
int getSampleRate();
|
||||||
int getEffectiveSampleRate();
|
int getEffectiveSampleRate();
|
||||||
double getMagSq() const { return m_objMagSqAverage.average(); } //!< Beware this is scaled to 2^30
|
double getMagSq() const { return m_objMagSqAverage.average(); } //!< Beware this is scaled to 2^30
|
||||||
|
bool getBFOLocked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ATVConfigPrivate
|
struct ATVConfigPrivate
|
||||||
@ -218,14 +224,16 @@ private:
|
|||||||
float fltRFBandwidth,
|
float fltRFBandwidth,
|
||||||
float fltRFOppBandwidth,
|
float fltRFOppBandwidth,
|
||||||
bool blnFFTFiltering,
|
bool blnFFTFiltering,
|
||||||
bool blndecimatorEnable)
|
bool blndecimatorEnable,
|
||||||
|
int intBFOFrequency)
|
||||||
{
|
{
|
||||||
return new MsgConfigureRFATVDemod(
|
return new MsgConfigureRFATVDemod(
|
||||||
enmModulation,
|
enmModulation,
|
||||||
fltRFBandwidth,
|
fltRFBandwidth,
|
||||||
fltRFOppBandwidth,
|
fltRFOppBandwidth,
|
||||||
blnFFTFiltering,
|
blnFFTFiltering,
|
||||||
blndecimatorEnable);
|
blndecimatorEnable,
|
||||||
|
intBFOFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATVRFConfig m_objMsgConfig;
|
ATVRFConfig m_objMsgConfig;
|
||||||
@ -236,7 +244,8 @@ private:
|
|||||||
float fltRFBandwidth,
|
float fltRFBandwidth,
|
||||||
float fltRFOppBandwidth,
|
float fltRFOppBandwidth,
|
||||||
bool blnFFTFiltering,
|
bool blnFFTFiltering,
|
||||||
bool blndecimatorEnable) :
|
bool blndecimatorEnable,
|
||||||
|
float fltBFOFrequency) :
|
||||||
Message()
|
Message()
|
||||||
{
|
{
|
||||||
m_objMsgConfig.m_enmModulation = enmModulation;
|
m_objMsgConfig.m_enmModulation = enmModulation;
|
||||||
@ -244,6 +253,7 @@ private:
|
|||||||
m_objMsgConfig.m_fltRFOppBandwidth = fltRFOppBandwidth;
|
m_objMsgConfig.m_fltRFOppBandwidth = fltRFOppBandwidth;
|
||||||
m_objMsgConfig.m_blnFFTFiltering = blnFFTFiltering;
|
m_objMsgConfig.m_blnFFTFiltering = blnFFTFiltering;
|
||||||
m_objMsgConfig.m_blndecimatorEnable = blndecimatorEnable;
|
m_objMsgConfig.m_blndecimatorEnable = blndecimatorEnable;
|
||||||
|
m_objMsgConfig.m_fltBFOFrequency = fltBFOFrequency;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -286,6 +296,8 @@ private:
|
|||||||
MovingAverage<double> m_objMagSqAverage;
|
MovingAverage<double> m_objMagSqAverage;
|
||||||
|
|
||||||
NCO m_nco;
|
NCO m_nco;
|
||||||
|
SimplePhaseLock m_bfoPLL;
|
||||||
|
SecondOrderRecursiveFilter m_bfoFilter;
|
||||||
|
|
||||||
// Interpolator group for decimation and/or double sideband RF filtering
|
// Interpolator group for decimation and/or double sideband RF filtering
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
|
@ -105,6 +105,7 @@ QByteArray ATVDemodGUI::serialize() const
|
|||||||
s.writeBool(11, ui->halfImage->isChecked());
|
s.writeBool(11, ui->halfImage->isChecked());
|
||||||
s.writeS32(12, ui->rfBW->value());
|
s.writeS32(12, ui->rfBW->value());
|
||||||
s.writeS32(13, ui->rfOppBW->value());
|
s.writeS32(13, ui->rfOppBW->value());
|
||||||
|
s.writeS32(14, ui->bfo->value());
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -160,6 +161,8 @@ bool ATVDemodGUI::deserialize(const QByteArray& arrData)
|
|||||||
ui->rfBW->setValue(tmp);
|
ui->rfBW->setValue(tmp);
|
||||||
d.readS32(13, &tmp, 10);
|
d.readS32(13, &tmp, 10);
|
||||||
ui->rfOppBW->setValue(tmp);
|
ui->rfOppBW->setValue(tmp);
|
||||||
|
d.readS32(14, &tmp, 10);
|
||||||
|
ui->bfo->setValue(tmp);
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
m_objChannelMarker.blockSignals(false);
|
m_objChannelMarker.blockSignals(false);
|
||||||
@ -336,7 +339,8 @@ void ATVDemodGUI::applyRFSettings()
|
|||||||
ui->rfBW->value() * 100000.0f,
|
ui->rfBW->value() * 100000.0f,
|
||||||
ui->rfOppBW->value() * 100000.0f,
|
ui->rfOppBW->value() * 100000.0f,
|
||||||
ui->rfFiltering->isChecked(),
|
ui->rfFiltering->isChecked(),
|
||||||
ui->decimatorEnable->isChecked());
|
ui->decimatorEnable->isChecked(),
|
||||||
|
ui->bfo->value() * 10.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,9 +353,9 @@ void ATVDemodGUI::setChannelMarkerBandwidth()
|
|||||||
m_objChannelMarker.setBandwidth(ui->rfBW->value()*100000);
|
m_objChannelMarker.setBandwidth(ui->rfBW->value()*100000);
|
||||||
m_objChannelMarker.setOppositeBandwidth(ui->rfOppBW->value()*100000);
|
m_objChannelMarker.setOppositeBandwidth(ui->rfOppBW->value()*100000);
|
||||||
|
|
||||||
if (ui->modulation->currentIndex() == (int) ATVDemod::ATV_VAML) {
|
if (ui->modulation->currentIndex() == (int) ATVDemod::ATV_LSB) {
|
||||||
m_objChannelMarker.setSidebands(ChannelMarker::vlsb);
|
m_objChannelMarker.setSidebands(ChannelMarker::vlsb);
|
||||||
} else if (ui->modulation->currentIndex() == (int) ATVDemod::ATV_VAMU) {
|
} else if (ui->modulation->currentIndex() == (int) ATVDemod::ATV_USB) {
|
||||||
m_objChannelMarker.setSidebands(ChannelMarker::vusb);
|
m_objChannelMarker.setSidebands(ChannelMarker::vusb);
|
||||||
} else {
|
} else {
|
||||||
m_objChannelMarker.setSidebands(ChannelMarker::vusb);
|
m_objChannelMarker.setSidebands(ChannelMarker::vusb);
|
||||||
@ -413,6 +417,12 @@ void ATVDemodGUI::tick()
|
|||||||
m_objMagSqAverage.feed(m_objATVDemod->getMagSq());
|
m_objMagSqAverage.feed(m_objATVDemod->getMagSq());
|
||||||
double magSqDB = CalcDb::dbPower(m_objMagSqAverage.average() / (1<<30));
|
double magSqDB = CalcDb::dbPower(m_objMagSqAverage.average() / (1<<30));
|
||||||
ui->channePowerText->setText(tr("%1 dB").arg(magSqDB, 0, 'f', 1));
|
ui->channePowerText->setText(tr("%1 dB").arg(magSqDB, 0, 'f', 1));
|
||||||
|
|
||||||
|
if (m_objATVDemod->getBFOLocked()) {
|
||||||
|
ui->bfoLockedLabel->setStyleSheet("QLabel { background-color : green; }");
|
||||||
|
} else {
|
||||||
|
ui->bfoLockedLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_intTickCount = 0;
|
m_intTickCount = 0;
|
||||||
@ -525,3 +535,9 @@ void ATVDemodGUI::on_deltaFrequencyMinus_toggled(bool minus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ATVDemodGUI::on_bfo_valueChanged(int value)
|
||||||
|
{
|
||||||
|
ui->bfoText->setText(QString("%1").arg(value * 10.0, 0, 'f', 0));
|
||||||
|
applyRFSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ private slots:
|
|||||||
void on_decimatorEnable_toggled(bool checked);
|
void on_decimatorEnable_toggled(bool checked);
|
||||||
void on_deltaFrequency_changed(quint64 value);
|
void on_deltaFrequency_changed(quint64 value);
|
||||||
void on_deltaFrequencyMinus_toggled(bool minus);
|
void on_deltaFrequencyMinus_toggled(bool minus);
|
||||||
|
void on_bfo_valueChanged(int value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ATVDemodGUI* ui;
|
Ui::ATVDemodGUI* ui;
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>501</width>
|
<width>501</width>
|
||||||
<height>71</height>
|
<height>81</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -52,23 +52,6 @@
|
|||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="rfSettings1Layout">
|
<layout class="QHBoxLayout" name="rfSettings1Layout">
|
||||||
<item>
|
|
||||||
<widget class="ButtonSwitch" name="decimatorEnable">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Toggle decimator on/off</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../sdrbase/resources/res.qrc">
|
|
||||||
<normaloff>:/arrow_down.png</normaloff>:/arrow_down.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="deltaFrequencyLayout">
|
<layout class="QHBoxLayout" name="deltaFrequencyLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -124,6 +107,30 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="decimatorEnable">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Toggle decimator on/off</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../sdrbase/resources/res.qrc">
|
||||||
|
<normaloff>:/arrow_down.png</normaloff>:/arrow_down.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="channelSampleRateText">
|
<widget class="QLabel" name="channelSampleRateText">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
@ -144,35 +151,77 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="modulation">
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="bfoLockedLabel">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>22</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="../../../sdrbase/resources/res.qrc">:/carrier.png</pixmap>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDial" name="bfo">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>22</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Modulation type</string>
|
<string>BFO frequency adjust</string>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<property name="minimum">
|
||||||
<property name="text">
|
<number>-500</number>
|
||||||
<string>FM 1</string>
|
|
||||||
</property>
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>500</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<widget class="QLabel" name="bfoText">
|
||||||
<string>FM 2</string>
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>BFO frequency (Hz)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<widget class="Line" name="line_2">
|
||||||
<string>AM</string>
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>VAMU</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>VAML</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -211,6 +260,38 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="rfSettings2Layout">
|
<layout class="QHBoxLayout" name="rfSettings2Layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="modulation">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Modulation type</string>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>FM 1</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>FM 2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>AM</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>USB</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>LSB</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="ButtonSwitch" name="rfFiltering">
|
<widget class="ButtonSwitch" name="rfFiltering">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -112,6 +112,24 @@ private:
|
|||||||
std::vector<PpsEvent> m_pps_events;
|
std::vector<PpsEvent> m_pps_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SimplePhaseLock : public PhaseLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SimplePhaseLock(Real freq, Real bandwidth, Real minsignal) :
|
||||||
|
PhaseLock(freq, bandwidth, minsignal)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~SimplePhaseLock()
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void processPhase(Real *samples_out) const
|
||||||
|
{
|
||||||
|
samples_out[0] = m_psin; // f Pilot
|
||||||
|
samples_out[1] = m_pcos; // f Pilot
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class StereoPhaseLock : public PhaseLock
|
class StereoPhaseLock : public PhaseLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
69
sdrbase/dsp/recursivefilters.cpp
Normal file
69
sdrbase/dsp/recursivefilters.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include "recursivefilters.h"
|
||||||
|
|
||||||
|
SecondOrderRecursiveFilter::SecondOrderRecursiveFilter(float samplingFrequency, float centerFrequency, float r) :
|
||||||
|
m_r(r),
|
||||||
|
m_frequencyRatio(centerFrequency/samplingFrequency)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondOrderRecursiveFilter::~SecondOrderRecursiveFilter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void SecondOrderRecursiveFilter::setFrequencies(float samplingFrequency, float centerFrequency)
|
||||||
|
{
|
||||||
|
m_frequencyRatio = centerFrequency / samplingFrequency;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecondOrderRecursiveFilter::setR(float r)
|
||||||
|
{
|
||||||
|
m_r = r;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
short SecondOrderRecursiveFilter::run(short sample)
|
||||||
|
{
|
||||||
|
m_v[0] = ((1.0f - m_r) * (float) sample) + (2.0f * m_r * cos(2.0*M_PI*m_frequencyRatio) * m_v[1]) - (m_r * m_r * m_v[2]);
|
||||||
|
float y = m_v[0] - m_v[2];
|
||||||
|
m_v[2] = m_v[1];
|
||||||
|
m_v[1] = m_v[0];
|
||||||
|
|
||||||
|
return (short) y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SecondOrderRecursiveFilter::run(float sample)
|
||||||
|
{
|
||||||
|
m_v[0] = ((1.0f - m_r) * sample) + (2.0f * m_r * cos(2.0*M_PI*m_frequencyRatio) * m_v[1]) - (m_r * m_r * m_v[2]);
|
||||||
|
float y = m_v[0] - m_v[2];
|
||||||
|
m_v[2] = m_v[1];
|
||||||
|
m_v[1] = m_v[0];
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecondOrderRecursiveFilter::init()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
m_v[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
45
sdrbase/dsp/recursivefilters.h
Normal file
45
sdrbase/dsp/recursivefilters.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRBASE_DSP_RECURSIVEFILTERS_H_
|
||||||
|
#define SDRBASE_DSP_RECURSIVEFILTERS_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \Brief: This is a second order bandpass filter using recursive method. r is in range ]0..1[ the higher the steeper the filter.
|
||||||
|
* inspired by:http://www.ece.umd.edu/~tretter/commlab/c6713slides/FSKSlides.pdf
|
||||||
|
*/
|
||||||
|
class SecondOrderRecursiveFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SecondOrderRecursiveFilter(float samplingFrequency, float centerFrequency, float r);
|
||||||
|
~SecondOrderRecursiveFilter();
|
||||||
|
|
||||||
|
void setFrequencies(float samplingFrequency, float centerFrequency);
|
||||||
|
void setR(float r);
|
||||||
|
short run(short sample);
|
||||||
|
float run(float sample);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
float m_r;
|
||||||
|
float m_frequencyRatio;
|
||||||
|
float m_v[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SDRBASE_DSP_RECURSIVEFILTERS_H_ */
|
Loading…
Reference in New Issue
Block a user