1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

NFM demod: added high pass audio filter control

This commit is contained in:
f4exb 2019-05-17 22:06:59 +02:00
parent 2d44fa3b99
commit 5096816143
7 changed files with 43 additions and 5 deletions

View File

@ -90,7 +90,7 @@ NFMDemod::NFMDemod(DeviceAPI *devieAPI) :
m_ctcssDetector.setCoefficients(m_audioSampleRate/16, m_audioSampleRate/8.0f); // 0.5s / 2 Hz resolution m_ctcssDetector.setCoefficients(m_audioSampleRate/16, m_audioSampleRate/8.0f); // 0.5s / 2 Hz resolution
m_afSquelch.setCoefficients(m_audioSampleRate/2000, 600, m_audioSampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay m_afSquelch.setCoefficients(m_audioSampleRate/2000, 600, m_audioSampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay
m_lowpass.create(301, m_audioSampleRate, 250.0); m_ctcssLowpass.create(301, m_audioSampleRate, 250.0);
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true); applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
applySettings(m_settings, true); applySettings(m_settings, true);
@ -247,7 +247,7 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
{ {
if (m_settings.m_ctcssOn) if (m_settings.m_ctcssOn)
{ {
Real ctcss_sample = m_lowpass.filter(demod * m_discriCompensation); Real ctcss_sample = m_ctcssLowpass.filter(demod * m_discriCompensation);
if ((m_sampleCount & 7) == 7) // decimate 48k -> 6k if ((m_sampleCount & 7) == 7) // decimate 48k -> 6k
{ {
@ -287,7 +287,11 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
} }
else else
{ {
sample = m_bandpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume; if (m_settings.m_highPass) {
sample = m_bandpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume;
} else {
sample = m_lowpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume;
}
} }
} }
else else
@ -436,8 +440,9 @@ void NFMDemod::applyAudioSampleRate(int sampleRate)
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;
m_lowpass.create(301, sampleRate, 250.0); m_ctcssLowpass.create(301, sampleRate, 250.0);
m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth); m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth);
m_lowpass.create(301, sampleRate, m_settings.m_afBandwidth);
m_squelchGate = (sampleRate / 100) * m_settings.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate m_squelchGate = (sampleRate / 100) * m_settings.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate
m_squelchCount = 0; // reset squelch open counter m_squelchCount = 0; // reset squelch open counter
m_ctcssDetector.setCoefficients(sampleRate/16, sampleRate/8.0f); // 0.5s / 2 Hz resolution m_ctcssDetector.setCoefficients(sampleRate/16, sampleRate/8.0f); // 0.5s / 2 Hz resolution
@ -499,6 +504,7 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force)
<< " m_squelch: " << settings.m_squelch << " m_squelch: " << settings.m_squelch
<< " m_ctcssIndex: " << settings.m_ctcssIndex << " m_ctcssIndex: " << settings.m_ctcssIndex
<< " m_ctcssOn: " << settings.m_ctcssOn << " m_ctcssOn: " << settings.m_ctcssOn
<< " m_highPass: " << m_settings.m_highPass
<< " m_audioMute: " << settings.m_audioMute << " m_audioMute: " << settings.m_audioMute
<< " m_audioDeviceName: " << settings.m_audioDeviceName << " m_audioDeviceName: " << settings.m_audioDeviceName
<< " m_useReverseAPI: " << settings.m_useReverseAPI << " m_useReverseAPI: " << settings.m_useReverseAPI
@ -550,6 +556,7 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force)
reverseAPIKeys.append("afBandwidth"); reverseAPIKeys.append("afBandwidth");
m_settingsMutex.lock(); m_settingsMutex.lock();
m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_afBandwidth); m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_afBandwidth);
m_lowpass.create(301, m_audioSampleRate, settings.m_afBandwidth);
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -591,6 +598,10 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force)
setSelectedCtcssIndex(settings.m_ctcssIndex); setSelectedCtcssIndex(settings.m_ctcssIndex);
} }
if ((settings.m_highPass != m_settings.m_highPass) || force) {
reverseAPIKeys.append("highPass");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{ {
reverseAPIKeys.append("audioDeviceName"); reverseAPIKeys.append("audioDeviceName");

View File

@ -220,8 +220,9 @@ private:
Interpolator m_interpolator; Interpolator m_interpolator;
Real m_interpolatorDistance; Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain; Real m_interpolatorDistanceRemain;
Lowpass<Real> m_lowpass; Lowpass<Real> m_ctcssLowpass;
Bandpass<Real> m_bandpass; Bandpass<Real> m_bandpass;
Lowpass<Real> m_lowpass;
CTCSSDetector m_ctcssDetector; CTCSSDetector m_ctcssDetector;
int m_ctcssIndex; // 0 for nothing detected int m_ctcssIndex; // 0 for nothing detected
int m_ctcssIndexSelected; int m_ctcssIndexSelected;

View File

@ -201,6 +201,12 @@ void NFMDemodGUI::on_ctcssOn_toggled(bool checked)
applySettings(); applySettings();
} }
void NFMDemodGUI::on_highPassFilter_toggled(bool checked)
{
m_settings.m_highPass = checked;
applySettings();
}
void NFMDemodGUI::on_audioMute_toggled(bool checked) void NFMDemodGUI::on_audioMute_toggled(bool checked)
{ {
m_settings.m_audioMute = checked; m_settings.m_audioMute = checked;
@ -398,6 +404,7 @@ void NFMDemodGUI::displaySettings()
} }
ui->ctcssOn->setChecked(m_settings.m_ctcssOn); ui->ctcssOn->setChecked(m_settings.m_ctcssOn);
ui->highPassFilter->setChecked(m_settings.m_highPass);
ui->audioMute->setChecked(m_settings.m_audioMute); ui->audioMute->setChecked(m_settings.m_audioMute);
ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex); ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex);

View File

@ -76,6 +76,7 @@ private slots:
void on_squelch_valueChanged(int value); void on_squelch_valueChanged(int value);
void on_ctcss_currentIndexChanged(int index); void on_ctcss_currentIndexChanged(int index);
void on_ctcssOn_toggled(bool checked); void on_ctcssOn_toggled(bool checked);
void on_highPassFilter_toggled(bool checked);
void on_audioMute_toggled(bool checked); void on_audioMute_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p); void onMenuDialogCalled(const QPoint& p);

View File

@ -574,6 +574,20 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="ButtonSwitch" name="highPassFilter">
<property name="toolTip">
<string>High pass audio filter</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/filter_highpass.png</normaloff>:/filter_highpass.png</iconset>
</property>
</widget>
</item>
<item> <item>
<widget class="QToolButton" name="audioMute"> <widget class="QToolButton" name="audioMute">
<property name="toolTip"> <property name="toolTip">

View File

@ -53,6 +53,7 @@ void NFMDemodSettings::resetToDefaults()
m_rgbColor = QColor(255, 0, 0).rgb(); m_rgbColor = QColor(255, 0, 0).rgb();
m_title = "NFM Demodulator"; m_title = "NFM Demodulator";
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
m_highPass = true;
m_useReverseAPI = false; m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888; m_reverseAPIPort = 8888;
@ -68,6 +69,7 @@ QByteArray NFMDemodSettings::serialize() const
s.writeS32(3, m_afBandwidth/1000.0); s.writeS32(3, m_afBandwidth/1000.0);
s.writeS32(4, m_volume*10.0); s.writeS32(4, m_volume*10.0);
s.writeS32(5, static_cast<int>(m_squelch)); s.writeS32(5, static_cast<int>(m_squelch));
s.writeBool(6, m_highPass);
s.writeU32(7, m_rgbColor); s.writeU32(7, m_rgbColor);
s.writeS32(8, m_ctcssIndex); s.writeS32(8, m_ctcssIndex);
s.writeBool(9, m_ctcssOn); s.writeBool(9, m_ctcssOn);
@ -123,6 +125,7 @@ bool NFMDemodSettings::deserialize(const QByteArray& data)
m_volume = tmp / 10.0; m_volume = tmp / 10.0;
d.readS32(5, &tmp, -30); d.readS32(5, &tmp, -30);
m_squelch = (tmp < -100 ? tmp/10 : tmp) * 1.0; m_squelch = (tmp < -100 ? tmp/10 : tmp) * 1.0;
d.readBool(6, &m_highPass, true);
d.readU32(7, &m_rgbColor, QColor(255, 0, 0).rgb()); d.readU32(7, &m_rgbColor, QColor(255, 0, 0).rgb());
d.readS32(8, &m_ctcssIndex, 0); d.readS32(8, &m_ctcssIndex, 0);
d.readBool(9, &m_ctcssOn, false); d.readBool(9, &m_ctcssOn, false);

View File

@ -42,6 +42,7 @@ struct NFMDemodSettings
quint32 m_rgbColor; quint32 m_rgbColor;
QString m_title; QString m_title;
QString m_audioDeviceName; QString m_audioDeviceName;
bool m_highPass;
bool m_useReverseAPI; bool m_useReverseAPI;
QString m_reverseAPIAddress; QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort; uint16_t m_reverseAPIPort;