AM Demod: added optional bandpass boxcar filter

This commit is contained in:
f4exb 2017-05-12 19:21:52 +02:00
parent b24ac8fa38
commit 375f327004
7 changed files with 81 additions and 24 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -63,9 +63,9 @@ AMDemod::~AMDemod()
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
}
void AMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real volume, Real squelch, bool audioMute)
void AMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real volume, Real squelch, bool audioMute, bool bandpassEnable)
{
Message* cmd = MsgConfigureAMDemod::create(rfBandwidth, volume, squelch, audioMute);
Message* cmd = MsgConfigureAMDemod::create(rfBandwidth, volume, squelch, audioMute, bandpassEnable);
messageQueue->push(cmd);
}
@ -157,6 +157,7 @@ bool AMDemod::handleMessage(const Message& cmd)
m_config.m_volume = cfg.getVolume();
m_config.m_squelch = cfg.getSquelch();
m_config.m_audioMute = cfg.getAudioMute();
m_config.m_bandpassEnable = cfg.getBandpassEnable();
apply();
@ -164,7 +165,8 @@ bool AMDemod::handleMessage(const Message& cmd)
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
<< " m_volume: " << m_config.m_volume
<< " m_squelch: " << m_config.m_squelch
<< " m_audioMute: " << m_config.m_audioMute;
<< " m_audioMute: " << m_config.m_audioMute
<< " m_bandpassEnable: " << m_config.m_bandpassEnable;
return true;
}
@ -185,12 +187,14 @@ void AMDemod::apply()
if((m_config.m_inputSampleRate != m_running.m_inputSampleRate) ||
(m_config.m_rfBandwidth != m_running.m_rfBandwidth) ||
(m_config.m_audioSampleRate != m_running.m_audioSampleRate))
(m_config.m_audioSampleRate != m_running.m_audioSampleRate) ||
(m_config.m_bandpassEnable != m_running.m_bandpassEnable))
{
m_settingsMutex.lock();
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2);
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2f);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_audioSampleRate;
m_bandpass.create(301, m_config.m_audioSampleRate, 300.0, m_config.m_rfBandwidth / 2.0f);
m_settingsMutex.unlock();
}
@ -207,4 +211,5 @@ void AMDemod::apply()
m_running.m_volume = m_config.m_volume;
m_running.m_audioSampleRate = m_config.m_audioSampleRate;
m_running.m_audioMute = m_config.m_audioMute;
m_running.m_bandpassEnable = m_config.m_bandpassEnable;
}

View File

@ -24,6 +24,7 @@
#include "dsp/interpolator.h"
#include "dsp/movingaverage.h"
#include "dsp/agc.h"
#include "dsp/bandpass.h"
#include "audio/audiofifo.h"
#include "util/message.h"
@ -33,7 +34,7 @@ public:
AMDemod();
~AMDemod();
void configure(MessageQueue* messageQueue, Real rfBandwidth, Real volume, Real squelch, bool audioMute);
void configure(MessageQueue* messageQueue, Real rfBandwidth, Real volume, Real squelch, bool audioMute, bool bandpassEnable);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
virtual void start();
@ -62,10 +63,11 @@ private:
Real getVolume() const { return m_volume; }
Real getSquelch() const { return m_squelch; }
bool getAudioMute() const { return m_audioMute; }
bool getBandpassEnable() const { return m_bandpassEnable; }
static MsgConfigureAMDemod* create(Real rfBandwidth, Real volume, Real squelch, bool audioMute)
static MsgConfigureAMDemod* create(Real rfBandwidth, Real volume, Real squelch, bool audioMute, bool bandpassEnable)
{
return new MsgConfigureAMDemod(rfBandwidth, volume, squelch, audioMute);
return new MsgConfigureAMDemod(rfBandwidth, volume, squelch, audioMute, bandpassEnable);
}
private:
@ -73,13 +75,15 @@ private:
Real m_volume;
Real m_squelch;
bool m_audioMute;
bool m_bandpassEnable;
MsgConfigureAMDemod(Real rfBandwidth, Real volume, Real squelch, bool audioMute) :
MsgConfigureAMDemod(Real rfBandwidth, Real volume, Real squelch, bool audioMute, bool bandpassEnable) :
Message(),
m_rfBandwidth(rfBandwidth),
m_volume(volume),
m_squelch(squelch),
m_audioMute(audioMute)
m_audioMute(audioMute),
m_bandpassEnable(bandpassEnable)
{ }
};
@ -102,6 +106,7 @@ private:
Real m_volume;
quint32 m_audioSampleRate;
bool m_audioMute;
bool m_bandpassEnable;
Config() :
m_inputSampleRate(-1),
@ -110,7 +115,8 @@ private:
m_squelch(0),
m_volume(0),
m_audioSampleRate(0),
m_audioMute(false)
m_audioMute(false),
m_bandpassEnable(false)
{ }
};
@ -132,6 +138,7 @@ private:
MovingAverage<double> m_movingAverage;
SimpleAGC m_volumeAGC;
Bandpass<Real> m_bandpass;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
@ -180,18 +187,18 @@ private:
if ((m_squelchCount >= m_running.m_audioSampleRate / 20) && !m_running.m_audioMute)
{
Real demod = sqrt(magsq);
if (demod > 1)
{
demod = 1;
}
m_volumeAGC.feed(demod);
demod /= m_volumeAGC.getValue();
if (m_running.m_bandpassEnable)
{
demod = m_bandpass.filter(demod);
demod /= 301.0f;
}
Real attack = m_squelchCount / (0.1f * m_running.m_audioSampleRate);
sample = (0.5 - demod) * attack * 2048 * m_running.m_volume;
// demod *= ((0.003 * attack) / m_volumeAGC.getValue());
// sample = demod * 32700 * 16;
m_squelchOpen = true;
}
else

View File

@ -88,6 +88,7 @@ QByteArray AMDemodGUI::serialize() const
s.writeS32(4, ui->volume->value());
s.writeS32(5, ui->squelch->value());
s.writeU32(7, m_channelMarker.getColor().rgb());
s.writeBool(8, ui->bandpassEnable->isChecked());
return s.final();
}
@ -106,6 +107,7 @@ bool AMDemodGUI::deserialize(const QByteArray& data)
QByteArray bytetmp;
quint32 u32tmp;
qint32 tmp;
bool boolTmp;
blockApplySettings(true);
m_channelMarker.blockSignals(true);
@ -126,6 +128,9 @@ bool AMDemodGUI::deserialize(const QByteArray& data)
m_channelMarker.setColor(u32tmp);
}
d.readBool(8, &boolTmp, false);
ui->bandpassEnable->setChecked(boolTmp);
blockApplySettings(false);
m_channelMarker.blockSignals(false);
@ -169,6 +174,11 @@ void AMDemodGUI::on_deltaFrequency_changed(quint64 value)
}
}
void AMDemodGUI::on_bandpassEnable_toggled(bool checked)
{
applySettings();
}
void AMDemodGUI::on_rfBW_valueChanged(int value)
{
ui->rfBWText->setText(QString("%1 kHz").arg(value / 10.0, 0, 'f', 1));
@ -284,7 +294,8 @@ void AMDemodGUI::applySettings()
ui->rfBW->value() * 100.0,
ui->volume->value() / 10.0,
ui->squelch->value(),
ui->audioMute->isChecked());
ui->audioMute->isChecked(),
ui->bandpassEnable->isChecked());
}
}

View File

@ -41,6 +41,7 @@ private slots:
void viewChanged();
void on_deltaFrequency_changed(quint64 value);
void on_deltaMinus_toggled(bool minus);
void on_bandpassEnable_toggled(bool checked);
void on_rfBW_valueChanged(int value);
void on_volume_valueChanged(int value);
void on_squelch_valueChanged(int value);

View File

@ -56,7 +56,16 @@
<property name="spacing">
<number>3</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -224,6 +233,21 @@
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="bandpassEnable">
<property name="toolTip">
<string>Toggle boxcar bandpass filter with 300 Hz low cuttof</string>
</property>
<property name="icon">
<iconset resource="../../../sdrbase/resources/res.qrc">
<normaloff>:/filter_bandpass.png</normaloff>
<normalon>:/filter_bandpass.png</normalon>:/filter_bandpass.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="rfBW">
<property name="toolTip">
@ -381,6 +405,11 @@
<header>gui/levelmeter.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrbase/resources/res.qrc"/>

View File

@ -30,14 +30,18 @@ Use this button to toggle audio mute for this channel. The button will light up
- bottom bar (blue green): instantaneous peak value
- tip vertical bar (bright green): peak hold value
<h3>6: RF bandwidth</h3>
<h3>6:Bandpass boxcar filter toggle</h3>
Use this button to enable or disable the bandpass boxcar (sharp) filter with low cutoff at 300 Hz and high cutoff at half the RF bandwidth. This may help readibility of low signals on air traffic communications but degrades audio on comfortable AM broadcast transmissions.
<h3>7: RF bandwidth</h3>
This is the bandwidth in kHz of the channel signal before demodulation. It can be set continuously in 1 kHz steps from 1 to 40 kHz.
<h3>7: Volume</h3>
<h3>8: Volume</h3>
This is the volume of the audio signal from 0.0 (mute) to 10.0 (maximum). It can be varied continuously in 0.1 steps using the dial button.
<h3>8: Squelch threshold</h3>
<h3>9: Squelch threshold</h3>
This is the squelch threshold in dB. The average total power received in the signal bandwidth before demodulation is compared to this value and the squelch input is open above this value. It can be varied continuously in 0.1 dB steps from 0.0 to -100.0 dB using the dial button.