AM Demod: added optional bandpass boxcar filter

pull/27/head
f4exb 2017-05-12 19:21:52 +02:00
rodzic b24ac8fa38
commit 375f327004
7 zmienionych plików z 81 dodań i 24 usunięć

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 17 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 19 KiB

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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());
}
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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"/>

Wyświetl plik

@ -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.