From 07be74701fe8a8ecea1500080f71b6982c104756 Mon Sep 17 00:00:00 2001 From: Kyle Reed <3761006+kallanreed@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:24:35 -0700 Subject: [PATCH] POCSAG Squelch and Filtering (#1424) * Disable audio processing when not using squelch * Add 2k4 lowpass fitler for 24Khz audio for POCSAG --- firmware/baseband/proc_pocsag.cpp | 17 ++++++++++------- firmware/baseband/proc_pocsag.hpp | 2 ++ firmware/common/dsp_iir_config.hpp | 6 ++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/firmware/baseband/proc_pocsag.cpp b/firmware/baseband/proc_pocsag.cpp index ebc3e0b92..48ec3959f 100644 --- a/firmware/baseband/proc_pocsag.cpp +++ b/firmware/baseband/proc_pocsag.cpp @@ -33,8 +33,6 @@ #include void POCSAGProcessor::execute(const buffer_c8_t& buffer) { - // This is called at 1500Hz - if (!configured) return; // Get 24kHz audio @@ -43,12 +41,14 @@ void POCSAGProcessor::execute(const buffer_c8_t& buffer) { const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); auto audio = demod.execute(channel_out, audio_buffer); - // Output audio pre-smoothing so squelch actually works. - // NB: It's useful to output *after* when debugging the smoothing filter. + // When use_squelch_ is true, AudioOutput applies filters + // which should eliminate the need to do this smoothing. + if (use_squelch_ == false) + smooth.Process(audio.p, audio.count); + + // NB: This applies audio filters in-place when use_squelch_ is true. audio_output.write(audio); - // Smooth the data to make decoding more accurate. - smooth.Process(audio.p, audio.count); processDemodulatedSamples(audio.p, 16); extractFrames(); } @@ -83,10 +83,13 @@ void POCSAGProcessor::on_message(const Message* const message) { case Message::ID::NBFMConfigure: { auto config = reinterpret_cast(message); + + use_squelch_ = config->squelch_level > 0; audio_output.configure( audio_24k_hpf_300hz_config, - audio_8k_deemph_300_6_config, + audio_24k_lpf_2400hz_config, config->squelch_level / 100.0); + audio_output.configure(use_squelch_); break; } diff --git a/firmware/baseband/proc_pocsag.hpp b/firmware/baseband/proc_pocsag.hpp index 57253f2d9..947ec7146 100644 --- a/firmware/baseband/proc_pocsag.hpp +++ b/firmware/baseband/proc_pocsag.hpp @@ -215,6 +215,8 @@ class POCSAGProcessor : public BasebandProcessor { int m_numCode{0}; bool m_inverted{false}; + bool use_squelch_ = false; + /* NB: Threads should be the last members in the class definition. */ BasebandThread baseband_thread{baseband_fs, this, baseband::Direction::Receive}; RSSIThread rssi_thread{}; diff --git a/firmware/common/dsp_iir_config.hpp b/firmware/common/dsp_iir_config.hpp index 177475df8..36133517f 100644 --- a/firmware/common/dsp_iir_config.hpp +++ b/firmware/common/dsp_iir_config.hpp @@ -77,6 +77,12 @@ constexpr iir_biquad_config_t audio_24k_deemph_300_6_config{ {0.03780475f, 0.03780475f, 0.00000000f}, {1.00000000f, -0.92439049f, 0.00000000f}}; +// scipy.signal.butter(1, 2400 / 12000.0, 'lowpass', analog=False) +// NOTE: Technically, order-1 filter, b[2] = a[2] = 0. +constexpr iir_biquad_config_t audio_24k_lpf_2400hz_config{ + {0.03780475f, 0.03780475f, 0.00000000f}, + {1.00000000f, -0.92439049f, 0.00000000f}}; + // scipy.signal.butter(1, 300 / 8000.0, 'lowpass', analog=False) // NOTE: Technically, order-1 filter, b[2] = a[2] = 0. constexpr iir_biquad_config_t audio_16k_deemph_300_6_config{