mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-10 10:33:29 -05:00
AM demod: synchronous AM: implemented sidebands selection
This commit is contained in:
parent
e9f64a05f2
commit
21840c5dd3
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,8 +1,10 @@
|
|||||||
sdrangel (3.14.7-1) unstable; urgency=medium
|
sdrangel (3.14.7-1) unstable; urgency=medium
|
||||||
|
|
||||||
* ChanelAnalyzerNG: added PLL option
|
* ChanelAnalyzerNG: added PLL option
|
||||||
|
* RTL-SDR: fixed inf/sup decimators
|
||||||
|
* AM demod: syncrhronous AM detection option
|
||||||
|
|
||||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 13 May 2018 20:14:18 +0200
|
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 May 2018 20:14:18 +0200
|
||||||
|
|
||||||
sdrangel (3.14.6-1) unstable; urgency=medium
|
sdrangel (3.14.6-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ 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)
|
||||||
{
|
{
|
||||||
@ -50,6 +49,7 @@ ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
|
|||||||
m_interpolatorDistanceRemain = 0.0f;
|
m_interpolatorDistanceRemain = 0.0f;
|
||||||
SSBFilter = new fftfilt(m_config.m_LowCutoff / m_config.m_inputSampleRate, m_config.m_Bandwidth / m_config.m_inputSampleRate, ssbFftLen);
|
SSBFilter = new fftfilt(m_config.m_LowCutoff / m_config.m_inputSampleRate, m_config.m_Bandwidth / m_config.m_inputSampleRate, ssbFftLen);
|
||||||
DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen);
|
DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen);
|
||||||
|
m_pll.computeCoefficients(0.05f, 0.707f, 1000.0f); // bandwidth, damping factor, loop gain
|
||||||
|
|
||||||
apply(true);
|
apply(true);
|
||||||
|
|
||||||
@ -249,6 +249,13 @@ void ChannelAnalyzerNG::apply(bool force)
|
|||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_running.m_pll != m_config.m_pll || force)
|
||||||
|
{
|
||||||
|
if (m_config.m_pll) {
|
||||||
|
m_pll.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_running.m_frequency = m_config.m_frequency;
|
m_running.m_frequency = m_config.m_frequency;
|
||||||
m_running.m_channelSampleRate = m_config.m_channelSampleRate;
|
m_running.m_channelSampleRate = m_config.m_channelSampleRate;
|
||||||
m_running.m_inputSampleRate = m_config.m_inputSampleRate;
|
m_running.m_inputSampleRate = m_config.m_inputSampleRate;
|
||||||
|
@ -25,7 +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 "dsp/phaselockcomplex.h"
|
||||||
#include "audio/audiofifo.h"
|
#include "audio/audiofifo.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
|
||||||
@ -148,6 +148,9 @@ public:
|
|||||||
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(); }
|
bool isPllLocked() const { return m_running.m_pll && m_pll.locked(); }
|
||||||
|
Real getPllFrequency() const { return m_pll.getFrequency(); }
|
||||||
|
Real getPllDeltaPhase() const { return m_pll.getDeltaPhi(); }
|
||||||
|
Real getPllPhase() const { return m_pll.getPhiHat(); }
|
||||||
|
|
||||||
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();
|
||||||
@ -203,7 +206,7 @@ private:
|
|||||||
bool m_useInterpolator;
|
bool m_useInterpolator;
|
||||||
|
|
||||||
NCOF m_nco;
|
NCOF m_nco;
|
||||||
SimplePhaseLock m_pll;
|
PhaseLockComplex m_pll;
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
@ -247,11 +250,13 @@ private:
|
|||||||
|
|
||||||
if (m_running.m_pll)
|
if (m_running.m_pll)
|
||||||
{
|
{
|
||||||
Real ncopll[2];
|
m_pll.feed(re, im);
|
||||||
m_pll.process(re, im, ncopll);
|
|
||||||
|
|
||||||
Real mixI = m_sum.real() * ncopll[0] - m_sum.imag() * ncopll[1];
|
// Use -fPLL to mix (exchange PLL real and image in the complex multiplication)
|
||||||
Real mixQ = m_sum.real() * ncopll[1] + m_sum.imag() * ncopll[0];
|
Real mixI = m_sum.real() * m_pll.getImag() - m_sum.imag() * m_pll.getReal();
|
||||||
|
Real mixQ = m_sum.real() * m_pll.getReal() + m_sum.imag() * m_pll.getImag();
|
||||||
|
// Real mixI = m_pll.getReal() * SDR_RX_SCALED;
|
||||||
|
// Real mixQ = m_pll.getImag() * SDR_RX_SCALED;
|
||||||
|
|
||||||
if (m_running.m_ssb & !m_usb)
|
if (m_running.m_ssb & !m_usb)
|
||||||
{ // invert spectrum for LSB
|
{ // invert spectrum for LSB
|
||||||
|
@ -243,6 +243,15 @@ void ChannelAnalyzerNGGUI::tick()
|
|||||||
} else {
|
} else {
|
||||||
ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ui->pll->isChecked())
|
||||||
|
{
|
||||||
|
int fHz = round(m_channelAnalyzer->getPllFrequency()*m_rate);
|
||||||
|
ui->pll->setToolTip(tr("PLL lock (f:%1 Hz e:%2 rad p:%3 rad)")
|
||||||
|
.arg(fHz)
|
||||||
|
.arg(m_channelAnalyzer->getPllDeltaPhase())
|
||||||
|
.arg(m_channelAnalyzer->getPllPhase()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
||||||
@ -257,8 +266,13 @@ void ChannelAnalyzerNGGUI::on_channelSampleRate_changed(quint64 value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked __attribute__((unused)))
|
void ChannelAnalyzerNGGUI::on_pll_toggled(bool checked)
|
||||||
{
|
{
|
||||||
|
if (!checked && m_usePll) {
|
||||||
|
ui->pll->setToolTip("PLL lock");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_usePll = checked;
|
||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,7 +413,8 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
|
|||||||
m_channelMarker(this),
|
m_channelMarker(this),
|
||||||
m_doApplySettings(true),
|
m_doApplySettings(true),
|
||||||
m_rate(6000),
|
m_rate(6000),
|
||||||
m_spanLog2(0)
|
m_spanLog2(0),
|
||||||
|
m_usePll(false)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
|
@ -66,6 +66,7 @@ private:
|
|||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
int m_rate; //!< sample rate after final in-channel decimation (spanlog2)
|
int m_rate; //!< sample rate after final in-channel decimation (spanlog2)
|
||||||
int m_spanLog2;
|
int m_spanLog2;
|
||||||
|
bool m_usePll;
|
||||||
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
|
MovingAverageUtil<Real, double, 40> m_channelPowerDbAvg;
|
||||||
|
|
||||||
ChannelAnalyzerNG* m_channelAnalyzer;
|
ChannelAnalyzerNG* m_channelAnalyzer;
|
||||||
|
@ -7,6 +7,7 @@ set(am_SOURCES
|
|||||||
amdemodgui.cpp
|
amdemodgui.cpp
|
||||||
amdemodsettings.cpp
|
amdemodsettings.cpp
|
||||||
amdemodplugin.cpp
|
amdemodplugin.cpp
|
||||||
|
amdemodssbdialog.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(am_HEADERS
|
set(am_HEADERS
|
||||||
@ -14,10 +15,12 @@ set(am_HEADERS
|
|||||||
amdemodgui.h
|
amdemodgui.h
|
||||||
amdemodsettings.h
|
amdemodsettings.h
|
||||||
amdemodplugin.h
|
amdemodplugin.h
|
||||||
|
amdemodssbdialog.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(am_FORMS
|
set(am_FORMS
|
||||||
amdemodgui.ui
|
amdemodgui.ui
|
||||||
|
amdemodssb.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
@ -67,6 +67,7 @@ AMDemod::AMDemod(DeviceSourceAPI *deviceAPI) :
|
|||||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||||
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
|
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
|
||||||
DSBFilter = new fftfilt((2.0f * m_settings.m_rfBandwidth) / m_audioSampleRate, 2 * 1024);
|
DSBFilter = new fftfilt((2.0f * m_settings.m_rfBandwidth) / m_audioSampleRate, 2 * 1024);
|
||||||
|
SSBFilter = new fftfilt(0.0f, m_settings.m_rfBandwidth / m_audioSampleRate, 1024);
|
||||||
|
|
||||||
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
|
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, true);
|
||||||
@ -89,6 +90,7 @@ AMDemod::~AMDemod()
|
|||||||
delete m_threadedChannelizer;
|
delete m_threadedChannelizer;
|
||||||
delete m_channelizer;
|
delete m_channelizer;
|
||||||
delete DSBFilter;
|
delete DSBFilter;
|
||||||
|
delete SSBFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused)))
|
void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused)))
|
||||||
@ -233,6 +235,7 @@ void AMDemod::applyAudioSampleRate(int sampleRate)
|
|||||||
m_inputMessageQueue.push(channelConfigMsg);
|
m_inputMessageQueue.push(channelConfigMsg);
|
||||||
|
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
|
|
||||||
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
||||||
m_interpolatorDistanceRemain = 0;
|
m_interpolatorDistanceRemain = 0;
|
||||||
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) sampleRate;
|
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) sampleRate;
|
||||||
@ -241,8 +244,14 @@ void AMDemod::applyAudioSampleRate(int sampleRate)
|
|||||||
m_squelchDelayLine.resize(sampleRate/5);
|
m_squelchDelayLine.resize(sampleRate/5);
|
||||||
DSBFilter->create_dsb_filter((2.0f * m_settings.m_rfBandwidth) / (float) sampleRate);
|
DSBFilter->create_dsb_filter((2.0f * m_settings.m_rfBandwidth) / (float) sampleRate);
|
||||||
m_pllFilt.create(101, sampleRate, 500.0);
|
m_pllFilt.create(101, sampleRate, 500.0);
|
||||||
m_settingsMutex.unlock();
|
|
||||||
|
|
||||||
|
if (m_settings.m_pll) {
|
||||||
|
m_volumeAGC.resizeNew(sampleRate, 0.003);
|
||||||
|
} else {
|
||||||
|
m_volumeAGC.resizeNew(sampleRate/10, 0.003);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settingsMutex.unlock();
|
||||||
m_audioSampleRate = sampleRate;
|
m_audioSampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +291,7 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
|
|||||||
<< " m_bandpassEnable: " << settings.m_bandpassEnable
|
<< " m_bandpassEnable: " << settings.m_bandpassEnable
|
||||||
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||||
<< " m_pll: " << settings.m_pll
|
<< " m_pll: " << settings.m_pll
|
||||||
|
<< " m_syncAMOperation: " << (int) settings.m_syncAMOperation
|
||||||
<< " force: " << force;
|
<< " force: " << force;
|
||||||
|
|
||||||
if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) ||
|
if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) ||
|
||||||
@ -314,6 +324,23 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((m_settings.m_pll != settings.m_pll) || force)
|
||||||
|
{
|
||||||
|
if (settings.m_pll)
|
||||||
|
{
|
||||||
|
m_volumeAGC.resizeNew(m_audioSampleRate/4, 0.003);
|
||||||
|
m_syncAMBuffIndex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_volumeAGC.resizeNew(m_audioSampleRate/10, 0.003);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_settings.m_syncAMOperation != settings.m_syncAMOperation) || force) {
|
||||||
|
m_syncAMBuffIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +167,12 @@ private:
|
|||||||
int m_magsqCount;
|
int m_magsqCount;
|
||||||
|
|
||||||
MovingAverageUtil<Real, double, 16> m_movingAverage;
|
MovingAverageUtil<Real, double, 16> m_movingAverage;
|
||||||
SimpleAGC<4096> m_volumeAGC;
|
SimpleAGC<4800> m_volumeAGC;
|
||||||
Bandpass<Real> m_bandpass;
|
Bandpass<Real> m_bandpass;
|
||||||
Lowpass<std::complex<float> > m_pllFilt;
|
Lowpass<std::complex<float> > m_pllFilt;
|
||||||
PhaseLockComplex m_pll;
|
PhaseLockComplex m_pll;
|
||||||
fftfilt* DSBFilter;
|
fftfilt* DSBFilter;
|
||||||
|
fftfilt* SSBFilter;
|
||||||
Real m_syncAMBuff[2*1024];
|
Real m_syncAMBuff[2*1024];
|
||||||
uint32_t m_syncAMBuffIndex;
|
uint32_t m_syncAMBuffIndex;
|
||||||
|
|
||||||
@ -238,16 +239,29 @@ private:
|
|||||||
|
|
||||||
fftfilt::cmplx *sideband;
|
fftfilt::cmplx *sideband;
|
||||||
std::complex<float> cs(yr, yi);
|
std::complex<float> cs(yr, yi);
|
||||||
int n_out = DSBFilter->runDSB(cs, &sideband, false);
|
int n_out;
|
||||||
|
|
||||||
|
if (m_settings.m_syncAMOperation == AMDemodSettings::SyncAMDSB) {
|
||||||
|
n_out = DSBFilter->runDSB(cs, &sideband, false);
|
||||||
|
} else {
|
||||||
|
n_out = SSBFilter->runSSB(cs, &sideband, m_settings.m_syncAMOperation == AMDemodSettings::SyncAMUSB, false);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n_out; i++)
|
for (int i = 0; i < n_out; i++)
|
||||||
{
|
{
|
||||||
m_syncAMBuff[i] = (sideband[i].real() + sideband[i].imag());
|
if (m_settings.m_syncAMOperation == AMDemodSettings::SyncAMDSB) {
|
||||||
|
m_syncAMBuff[i] = (sideband[i].real() + sideband[i].imag())/2.0f;
|
||||||
|
} else if (m_settings.m_syncAMOperation == AMDemodSettings::SyncAMUSB) {
|
||||||
|
m_syncAMBuff[i] = (sideband[i].real() + sideband[i].imag());
|
||||||
|
} else {
|
||||||
|
m_syncAMBuff[i] = (sideband[i].real() + sideband[i].imag());
|
||||||
|
}
|
||||||
|
|
||||||
m_syncAMBuffIndex = 0;
|
m_syncAMBuffIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_syncAMBuffIndex = m_syncAMBuffIndex < 2*1024 ? m_syncAMBuffIndex : 0;
|
m_syncAMBuffIndex = m_syncAMBuffIndex < 2*1024 ? m_syncAMBuffIndex : 0;
|
||||||
demod = m_syncAMBuff[m_syncAMBuffIndex++]*0.7*(SDR_RX_SCALEF/602.0f);
|
demod = m_syncAMBuff[m_syncAMBuffIndex++]*(SDR_RX_SCALEF/602.0f);
|
||||||
m_volumeAGC.feed(demod);
|
m_volumeAGC.feed(demod);
|
||||||
demod /= (10.0*m_volumeAGC.getValue());
|
demod /= (10.0*m_volumeAGC.getValue());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include "amdemodgui.h"
|
#include "amdemodgui.h"
|
||||||
|
#include "amdemodssbdialog.h"
|
||||||
|
|
||||||
#include "device/devicesourceapi.h"
|
#include "device/devicesourceapi.h"
|
||||||
#include "device/deviceuiset.h"
|
#include "device/deviceuiset.h"
|
||||||
@ -149,6 +150,12 @@ void AMDemodGUI::on_pll_toggled(bool checked)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AMDemodGUI::on_ssb_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_settings.m_syncAMOperation = checked ? m_samUSB ? AMDemodSettings::SyncAMUSB : AMDemodSettings::SyncAMLSB : AMDemodSettings::SyncAMDSB;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void AMDemodGUI::on_bandpassEnable_toggled(bool checked)
|
void AMDemodGUI::on_bandpassEnable_toggled(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_bandpassEnable = checked;
|
m_settings.m_bandpassEnable = checked;
|
||||||
@ -215,6 +222,7 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
|||||||
m_channelMarker(this),
|
m_channelMarker(this),
|
||||||
m_doApplySettings(true),
|
m_doApplySettings(true),
|
||||||
m_squelchOpen(false),
|
m_squelchOpen(false),
|
||||||
|
m_samUSB(true),
|
||||||
m_tickCount(0)
|
m_tickCount(0)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -230,6 +238,9 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
|||||||
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
|
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
|
||||||
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
|
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
|
||||||
|
|
||||||
|
CRightClickEnabler *samSidebandRightClickEnabler = new CRightClickEnabler(ui->ssb);
|
||||||
|
connect(samSidebandRightClickEnabler, SIGNAL(rightClick()), this, SLOT(samSSBSelect()));
|
||||||
|
|
||||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||||
@ -254,6 +265,11 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
|||||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||||
|
|
||||||
|
m_iconDSBUSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::Off);
|
||||||
|
m_iconDSBUSB.addPixmap(QPixmap("://usb.png"), QIcon::Normal, QIcon::On);
|
||||||
|
m_iconDSBLSB.addPixmap(QPixmap("://dsb.png"), QIcon::Normal, QIcon::Off);
|
||||||
|
m_iconDSBLSB.addPixmap(QPixmap("://lsb.png"), QIcon::Normal, QIcon::On);
|
||||||
|
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettings(true);
|
applySettings(true);
|
||||||
}
|
}
|
||||||
@ -314,6 +330,20 @@ void AMDemodGUI::displaySettings()
|
|||||||
ui->bandpassEnable->setChecked(m_settings.m_bandpassEnable);
|
ui->bandpassEnable->setChecked(m_settings.m_bandpassEnable);
|
||||||
ui->pll->setChecked(m_settings.m_pll);
|
ui->pll->setChecked(m_settings.m_pll);
|
||||||
|
|
||||||
|
if (m_settings.m_pll) {
|
||||||
|
if (m_settings.m_syncAMOperation == AMDemodSettings::SyncAMLSB) {
|
||||||
|
m_samUSB = false;
|
||||||
|
ui->ssb->setIcon(m_iconDSBLSB);
|
||||||
|
} else {
|
||||||
|
m_samUSB = true;
|
||||||
|
ui->ssb->setIcon(m_iconDSBUSB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->ssb->setIcon(m_iconDSBUSB);
|
||||||
|
}
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +370,26 @@ void AMDemodGUI::audioSelect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AMDemodGUI::samSSBSelect()
|
||||||
|
{
|
||||||
|
AMDemodSSBDialog ssbSelect(m_samUSB);
|
||||||
|
ssbSelect.exec();
|
||||||
|
|
||||||
|
ui->ssb->setIcon(ssbSelect.isUsb() ? m_iconDSBUSB : m_iconDSBLSB);
|
||||||
|
|
||||||
|
if (ssbSelect.isUsb() != m_samUSB)
|
||||||
|
{
|
||||||
|
qDebug("AMDemodGUI::samSSBSelect: %s", ssbSelect.isUsb() ? "usb" : "lsb");
|
||||||
|
m_samUSB = ssbSelect.isUsb();
|
||||||
|
|
||||||
|
if (m_settings.m_syncAMOperation != AMDemodSettings::SyncAMDSB)
|
||||||
|
{
|
||||||
|
m_settings.m_syncAMOperation = m_samUSB ? AMDemodSettings::SyncAMUSB : AMDemodSettings::SyncAMLSB;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AMDemodGUI::tick()
|
void AMDemodGUI::tick()
|
||||||
{
|
{
|
||||||
double magsqAvg, magsqPeak;
|
double magsqAvg, magsqPeak;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#ifndef INCLUDE_AMDEMODGUI_H
|
#ifndef INCLUDE_AMDEMODGUI_H
|
||||||
#define INCLUDE_AMDEMODGUI_H
|
#define INCLUDE_AMDEMODGUI_H
|
||||||
|
|
||||||
#include <plugin/plugininstancegui.h>
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include "plugin/plugininstancegui.h"
|
||||||
#include "gui/rollupwidget.h"
|
#include "gui/rollupwidget.h"
|
||||||
#include "dsp/channelmarker.h"
|
#include "dsp/channelmarker.h"
|
||||||
#include "dsp/movingaverage.h"
|
#include "dsp/movingaverage.h"
|
||||||
@ -50,9 +52,13 @@ private:
|
|||||||
|
|
||||||
AMDemod* m_amDemod;
|
AMDemod* m_amDemod;
|
||||||
bool m_squelchOpen;
|
bool m_squelchOpen;
|
||||||
|
bool m_samUSB;
|
||||||
uint32_t m_tickCount;
|
uint32_t m_tickCount;
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
|
|
||||||
|
QIcon m_iconDSBUSB;
|
||||||
|
QIcon m_iconDSBLSB;
|
||||||
|
|
||||||
explicit AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
explicit AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||||
virtual ~AMDemodGUI();
|
virtual ~AMDemodGUI();
|
||||||
|
|
||||||
@ -66,6 +72,7 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void on_deltaFrequency_changed(qint64 value);
|
void on_deltaFrequency_changed(qint64 value);
|
||||||
void on_pll_toggled(bool checked);
|
void on_pll_toggled(bool checked);
|
||||||
|
void on_ssb_toggled(bool checked);
|
||||||
void on_bandpassEnable_toggled(bool checked);
|
void on_bandpassEnable_toggled(bool checked);
|
||||||
void on_rfBW_valueChanged(int value);
|
void on_rfBW_valueChanged(int value);
|
||||||
void on_volume_valueChanged(int value);
|
void on_volume_valueChanged(int value);
|
||||||
@ -75,6 +82,7 @@ private slots:
|
|||||||
void onMenuDialogCalled(const QPoint& p);
|
void onMenuDialogCalled(const QPoint& p);
|
||||||
void handleInputMessages();
|
void handleInputMessages();
|
||||||
void audioSelect();
|
void audioSelect();
|
||||||
|
void samSSBSelect();
|
||||||
void tick();
|
void tick();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,6 +154,24 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="ssb">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Synchronous AM SSB/DSB toggle right click to select side band</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/dsb.png</normaloff>
|
||||||
|
<normalon>:/usb.png</normalon>:/dsb.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -39,6 +39,7 @@ void AMDemodSettings::resetToDefaults()
|
|||||||
m_title = "AM Demodulator";
|
m_title = "AM Demodulator";
|
||||||
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||||
m_pll = false;
|
m_pll = false;
|
||||||
|
m_syncAMOperation = SyncAMDSB;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AMDemodSettings::serialize() const
|
QByteArray AMDemodSettings::serialize() const
|
||||||
@ -58,6 +59,7 @@ QByteArray AMDemodSettings::serialize() const
|
|||||||
s.writeString(9, m_title);
|
s.writeString(9, m_title);
|
||||||
s.writeString(11, m_audioDeviceName);
|
s.writeString(11, m_audioDeviceName);
|
||||||
s.writeBool(12, m_pll);
|
s.writeBool(12, m_pll);
|
||||||
|
s.writeS32(13, (int) m_syncAMOperation);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -96,6 +98,8 @@ bool AMDemodSettings::deserialize(const QByteArray& data)
|
|||||||
d.readString(9, &m_title, "AM Demodulator");
|
d.readString(9, &m_title, "AM Demodulator");
|
||||||
d.readString(11, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
d.readString(11, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
||||||
d.readBool(12, &m_pll, false);
|
d.readBool(12, &m_pll, false);
|
||||||
|
d.readS32(13, &tmp, 0);
|
||||||
|
m_syncAMOperation = tmp < 0 ? SyncAMDSB : tmp > 2 ? SyncAMDSB : (SyncAMOperation) tmp;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,13 @@ class Serializable;
|
|||||||
|
|
||||||
struct AMDemodSettings
|
struct AMDemodSettings
|
||||||
{
|
{
|
||||||
|
enum SyncAMOperation
|
||||||
|
{
|
||||||
|
SyncAMDSB,
|
||||||
|
SyncAMUSB,
|
||||||
|
SyncAMLSB
|
||||||
|
};
|
||||||
|
|
||||||
qint32 m_inputFrequencyOffset;
|
qint32 m_inputFrequencyOffset;
|
||||||
Real m_rfBandwidth;
|
Real m_rfBandwidth;
|
||||||
Real m_squelch;
|
Real m_squelch;
|
||||||
@ -34,6 +41,7 @@ struct AMDemodSettings
|
|||||||
Serializable *m_channelMarker;
|
Serializable *m_channelMarker;
|
||||||
QString m_audioDeviceName;
|
QString m_audioDeviceName;
|
||||||
bool m_pll;
|
bool m_pll;
|
||||||
|
SyncAMOperation m_syncAMOperation;
|
||||||
|
|
||||||
AMDemodSettings();
|
AMDemodSettings();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
|
96
plugins/channelrx/demodam/amdemodssb.ui
Normal file
96
plugins/channelrx/demodam/amdemodssb.ui
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AMDemodSSBDialog</class>
|
||||||
|
<widget class="QDialog" name="AMDemodSSBDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>199</width>
|
||||||
|
<height>115</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Liberation Sans</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>SAM sideband selection</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="lsb">
|
||||||
|
<property name="text">
|
||||||
|
<string>LSB</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QRadioButton" name="usb">
|
||||||
|
<property name="text">
|
||||||
|
<string>USB</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>buttonBox</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AMDemodSSBDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>194</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>203</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AMDemodSSBDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>314</x>
|
||||||
|
<y>194</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>203</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
41
plugins/channelrx/demodam/amdemodssbdialog.cpp
Normal file
41
plugins/channelrx/demodam/amdemodssbdialog.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 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 "amdemodssbdialog.h"
|
||||||
|
#include "ui_amdemodssb.h"
|
||||||
|
|
||||||
|
AMDemodSSBDialog::AMDemodSSBDialog(bool usb, QWidget* parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::AMDemodSSBDialog),
|
||||||
|
m_usb(usb)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->usb->setChecked(usb);
|
||||||
|
ui->lsb->setChecked(!usb);
|
||||||
|
}
|
||||||
|
|
||||||
|
AMDemodSSBDialog::~AMDemodSSBDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMDemodSSBDialog::accept()
|
||||||
|
{
|
||||||
|
m_usb = ui->usb->isChecked();
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
plugins/channelrx/demodam/amdemodssbdialog.h
Normal file
43
plugins/channelrx/demodam/amdemodssbdialog.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 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 PLUGINS_CHANNELRX_DEMODAM_AMDEMODSSBDIALOG_H_
|
||||||
|
#define PLUGINS_CHANNELRX_DEMODAM_AMDEMODSSBDIALOG_H_
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AMDemodSSBDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AMDemodSSBDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AMDemodSSBDialog(bool usb, QWidget* parent = 0);
|
||||||
|
~AMDemodSSBDialog();
|
||||||
|
|
||||||
|
bool isUsb() const { return m_usb; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AMDemodSSBDialog* ui;
|
||||||
|
bool m_usb;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void accept();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PLUGINS_CHANNELRX_DEMODAM_AMDEMODSSBDIALOG_H_ */
|
@ -89,6 +89,13 @@ public:
|
|||||||
m_moving_average.resize(AvgSize, initial);
|
m_moving_average.resize(AvgSize, initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resizeNew(uint32_t newSize, Real initial, Real cutoff=0, Real clip=0)
|
||||||
|
{
|
||||||
|
m_cutoff = cutoff;
|
||||||
|
m_clip = clip;
|
||||||
|
m_moving_average.resize(newSize, initial);
|
||||||
|
}
|
||||||
|
|
||||||
void fill(double value)
|
void fill(double value)
|
||||||
{
|
{
|
||||||
m_moving_average.fill(value);
|
m_moving_average.fill(value);
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
#include "recursivefilters.h"
|
#include "recursivefilters.h"
|
||||||
|
|
||||||
#undef M_PI
|
#undef M_PI
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
|
|
||||||
SecondOrderRecursiveFilter::SecondOrderRecursiveFilter(float samplingFrequency, float centerFrequency, float r) :
|
SecondOrderRecursiveFilter::SecondOrderRecursiveFilter(float samplingFrequency, float centerFrequency, float r) :
|
||||||
m_r(r),
|
m_r(r),
|
||||||
m_frequencyRatio(centerFrequency/samplingFrequency)
|
m_frequencyRatio(centerFrequency/samplingFrequency),
|
||||||
|
m_f(cos(2.0*M_PI*(m_frequencyRatio)))
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -33,6 +34,7 @@ SecondOrderRecursiveFilter::~SecondOrderRecursiveFilter()
|
|||||||
void SecondOrderRecursiveFilter::setFrequencies(float samplingFrequency, float centerFrequency)
|
void SecondOrderRecursiveFilter::setFrequencies(float samplingFrequency, float centerFrequency)
|
||||||
{
|
{
|
||||||
m_frequencyRatio = centerFrequency / samplingFrequency;
|
m_frequencyRatio = centerFrequency / samplingFrequency;
|
||||||
|
m_f = cos(2.0*M_PI*m_frequencyRatio);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +46,7 @@ void SecondOrderRecursiveFilter::setR(float r)
|
|||||||
|
|
||||||
short SecondOrderRecursiveFilter::run(short sample)
|
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]);
|
m_v[0] = ((1.0f - m_r) * (float) sample) + (2.0f * m_r * m_f * m_v[1]) - (m_r * m_r * m_v[2]);
|
||||||
float y = m_v[0] - m_v[2];
|
float y = m_v[0] - m_v[2];
|
||||||
m_v[2] = m_v[1];
|
m_v[2] = m_v[1];
|
||||||
m_v[1] = m_v[0];
|
m_v[1] = m_v[0];
|
||||||
@ -54,7 +56,7 @@ short SecondOrderRecursiveFilter::run(short sample)
|
|||||||
|
|
||||||
float SecondOrderRecursiveFilter::run(float sample)
|
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]);
|
m_v[0] = ((1.0f - m_r) * sample) + (2.0f * m_r * m_f * m_v[1]) - (m_r * m_r * m_v[2]);
|
||||||
float y = m_v[0] - m_v[2];
|
float y = m_v[0] - m_v[2];
|
||||||
m_v[2] = m_v[1];
|
m_v[2] = m_v[1];
|
||||||
m_v[1] = m_v[0];
|
m_v[1] = m_v[0];
|
||||||
|
@ -39,6 +39,7 @@ private:
|
|||||||
|
|
||||||
float m_r;
|
float m_r;
|
||||||
float m_frequencyRatio;
|
float m_frequencyRatio;
|
||||||
|
float m_f;
|
||||||
float m_v[3];
|
float m_v[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user