From f46e20c977046d6e7dce1111063e150795586b9a Mon Sep 17 00:00:00 2001 From: Kyle Reed <3761006+kallanreed@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:05:49 -0700 Subject: [PATCH] Explain and clean up decimator scalars (#1422) --- firmware/baseband/dsp_decimate.hpp | 23 +++++++++++++++-------- firmware/baseband/proc_acars.cpp | 4 ++-- firmware/baseband/proc_afskrx.cpp | 4 ++-- firmware/baseband/proc_ais.cpp | 4 ++-- firmware/baseband/proc_am_audio.cpp | 4 ++-- firmware/baseband/proc_aprsrx.cpp | 4 ++-- firmware/baseband/proc_btlerx.cpp | 4 ++-- firmware/baseband/proc_capture.cpp | 25 ++++++++++--------------- firmware/baseband/proc_nfm_audio.cpp | 4 ++-- firmware/baseband/proc_nrfrx.cpp | 4 ++-- firmware/baseband/proc_pocsag.cpp | 4 ++-- firmware/baseband/proc_sonde.cpp | 4 ++-- firmware/baseband/proc_test.cpp | 4 ++-- firmware/baseband/proc_tpms.cpp | 4 ++-- firmware/baseband/proc_wfm_audio.cpp | 4 ++-- firmware/common/complex.hpp | 24 ------------------------ 16 files changed, 51 insertions(+), 73 deletions(-) diff --git a/firmware/baseband/dsp_decimate.hpp b/firmware/baseband/dsp_decimate.hpp index a76c0b034..a5f8a9cd2 100644 --- a/firmware/baseband/dsp_decimate.hpp +++ b/firmware/baseband/dsp_decimate.hpp @@ -23,19 +23,26 @@ #define __DSP_DECIMATE_H__ #include +#include #include #include -#include - -#include "utility.hpp" #include "dsp_types.hpp" - #include "simd.hpp" +#include "utility.hpp" namespace dsp { namespace decimate { +/* "Saturating" scalars used by decimators to scale either + * 8 or 16 bit complex values into 32 bit complex values. + * Some of the decimators accept a scale factor as part of + * configuration, which is then passed to scale_round_and_pack. */ +// c8_to_c32_sat_scalar == 2^25. 2^25 * 2^7 (signed C8 Max) == 2^32. +constexpr int32_t c8_to_c32_sat_scalar = 0x2000000; +// c16_to_c32_sat_scalar == 2^17. 2^17 * 2^15 (signed C16 Max) == 2^32. +constexpr int32_t c16_to_c32_sat_scalar = 0x20000; + class Complex8DecimateBy2CIC3 { public: buffer_c16_t execute( @@ -100,7 +107,7 @@ class FIRC8xR16x24FS4Decim4 { void configure( const std::array& taps, - const int32_t scale, + const int32_t scale = c8_to_c32_sat_scalar, const Shift shift = Shift::Down); buffer_c16_t execute( @@ -128,7 +135,7 @@ class FIRC8xR16x24FS4Decim8 { void configure( const std::array& taps, - const int32_t scale, + const int32_t scale = c8_to_c32_sat_scalar, const Shift shift = Shift::Down); buffer_c16_t execute( @@ -151,7 +158,7 @@ class FIRC16xR16x16Decim2 { void configure( const std::array& taps, - const int32_t scale); + const int32_t scale = c16_to_c32_sat_scalar); buffer_c16_t execute( const buffer_c16_t& src, @@ -173,7 +180,7 @@ class FIRC16xR16x32Decim8 { void configure( const std::array& taps, - const int32_t scale); + const int32_t scale = c16_to_c32_sat_scalar); buffer_c16_t execute( const buffer_c16_t& src, diff --git a/firmware/baseband/proc_acars.cpp b/firmware/baseband/proc_acars.cpp index 9a47cb1e3..023112e5b 100644 --- a/firmware/baseband/proc_acars.cpp +++ b/firmware/baseband/proc_acars.cpp @@ -29,8 +29,8 @@ #include "event_m4.hpp" ACARSProcessor::ACARSProcessor() { - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); packet.clear(); baseband_thread.start(); } diff --git a/firmware/baseband/proc_afskrx.cpp b/firmware/baseband/proc_afskrx.cpp index 609377160..27b1b4616 100644 --- a/firmware/baseband/proc_afskrx.cpp +++ b/firmware/baseband/proc_afskrx.cpp @@ -154,8 +154,8 @@ void AFSKRxProcessor::configure(const AFSKRxConfigureMessage& message) { const size_t demod_input_fs = channel_filter_output_fs;*/ - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); channel_filter.configure(taps_11k0_channel.taps, 2); demod.configure(audio_fs, 5000); diff --git a/firmware/baseband/proc_ais.cpp b/firmware/baseband/proc_ais.cpp index fbefa8a8d..6bb4a4aa0 100644 --- a/firmware/baseband/proc_ais.cpp +++ b/firmware/baseband/proc_ais.cpp @@ -28,8 +28,8 @@ #include "event_m4.hpp" AISProcessor::AISProcessor() { - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); baseband_thread.start(); } diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index aa9689ec1..160356303 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -89,8 +89,8 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) { constexpr size_t channel_filter_input_fs = decim_2_output_fs; // const size_t channel_filter_output_fs = channel_filter_input_fs / channel_filter_decimation_factor; - decim_0.configure(message.decim_0_filter.taps, 33554432); - decim_1.configure(message.decim_1_filter.taps, 131072); + decim_0.configure(message.decim_0_filter.taps); + decim_1.configure(message.decim_1_filter.taps); decim_2.configure(message.decim_2_filter.taps, decim_2_decimation_factor); channel_filter.configure(message.channel_filter.taps, channel_filter_decimation_factor); channel_filter_low_f = message.channel_filter.low_frequency_normalized * channel_filter_input_fs; diff --git a/firmware/baseband/proc_aprsrx.cpp b/firmware/baseband/proc_aprsrx.cpp index 08bde317c..616bbb417 100644 --- a/firmware/baseband/proc_aprsrx.cpp +++ b/firmware/baseband/proc_aprsrx.cpp @@ -223,8 +223,8 @@ void APRSRxProcessor::capture_config(const CaptureConfigMessage& message) { } void APRSRxProcessor::configure(const APRSRxConfigureMessage& message) { - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); channel_filter.configure(taps_11k0_channel.taps, 2); demod.configure(audio_fs, 5000); diff --git a/firmware/baseband/proc_btlerx.cpp b/firmware/baseband/proc_btlerx.cpp index d19263c74..ed39115ce 100644 --- a/firmware/baseband/proc_btlerx.cpp +++ b/firmware/baseband/proc_btlerx.cpp @@ -276,8 +276,8 @@ void BTLERxProcessor::on_message(const Message* const message) { void BTLERxProcessor::configure(const BTLERxConfigureMessage& message) { (void)message; // avoid warning - decim_0.configure(taps_200k_wfm_decim_0.taps, 33554432); - decim_1.configure(taps_200k_wfm_decim_1.taps, 131072); + decim_0.configure(taps_200k_wfm_decim_0.taps); + decim_1.configure(taps_200k_wfm_decim_1.taps); demod.configure(audio_fs, 5000); configured = true; diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index 135738025..c29255f1c 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -104,43 +104,38 @@ void CaptureProcessor::sample_rate_config(const SampleRateConfigMessage& message if (sample_rate >= 1'500'000) spectrum_interval_samples /= (sample_rate / 750'000); - // Mystery scalars for decimator configuration. - // TODO: figure these out and add a real comment. - constexpr int decim_0_scale = 0x2000000; - constexpr int decim_1_scale = 0x20000; - switch (message.oversample_rate) { case OversampleRate::x4: // M4 can't handle 2 decimation passes for sample rates needing x4. - decim_0.set().configure(taps_200k_decim_0.taps, decim_0_scale); + decim_0.set().configure(taps_200k_decim_0.taps); decim_1.set(); break; case OversampleRate::x8: // M4 can't handle 2 decimation passes for sample rates <= 600k. if (message.sample_rate < 600'000) { - decim_0.set().configure(taps_200k_decim_0.taps, decim_0_scale); - decim_1.set().configure(taps_200k_decim_1.taps, decim_1_scale); + decim_0.set().configure(taps_200k_decim_0.taps); + decim_1.set().configure(taps_200k_decim_1.taps); } else { // Using 180k taps to provide better filtering with a single pass. - decim_0.set().configure(taps_180k_wfm_decim_0.taps, decim_0_scale); + decim_0.set().configure(taps_180k_wfm_decim_0.taps); decim_1.set(); } break; case OversampleRate::x16: - decim_0.set().configure(taps_200k_decim_0.taps, decim_0_scale); - decim_1.set().configure(taps_200k_decim_1.taps, decim_1_scale); + decim_0.set().configure(taps_200k_decim_0.taps); + decim_1.set().configure(taps_200k_decim_1.taps); break; case OversampleRate::x32: - decim_0.set().configure(taps_200k_decim_0.taps, decim_0_scale); - decim_1.set().configure(taps_16k0_decim_1.taps, decim_1_scale); + decim_0.set().configure(taps_200k_decim_0.taps); + decim_1.set().configure(taps_16k0_decim_1.taps); break; case OversampleRate::x64: - decim_0.set().configure(taps_200k_decim_0.taps, decim_0_scale); - decim_1.set().configure(taps_16k0_decim_1.taps, decim_1_scale); + decim_0.set().configure(taps_200k_decim_0.taps); + decim_1.set().configure(taps_16k0_decim_1.taps); break; default: diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index e09db1c2a..6b4e61352 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -144,8 +144,8 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) { const size_t demod_input_fs = channel_filter_output_fs; - decim_0.configure(message.decim_0_filter.taps, 33554432); - decim_1.configure(message.decim_1_filter.taps, 131072); + decim_0.configure(message.decim_0_filter.taps); + decim_1.configure(message.decim_1_filter.taps); channel_filter.configure(message.channel_filter.taps, message.channel_decimation); demod.configure(demod_input_fs, message.deviation); channel_filter_low_f = message.channel_filter.low_frequency_normalized * channel_filter_input_fs; diff --git a/firmware/baseband/proc_nrfrx.cpp b/firmware/baseband/proc_nrfrx.cpp index 89dfc9c70..8403665f6 100644 --- a/firmware/baseband/proc_nrfrx.cpp +++ b/firmware/baseband/proc_nrfrx.cpp @@ -243,8 +243,8 @@ void NRFRxProcessor::on_message(const Message* const message) { void NRFRxProcessor::configure(const NRFRxConfigureMessage& message) { (void)message; // avoir unused warning - decim_0.configure(taps_200k_wfm_decim_0.taps, 33554432); - decim_1.configure(taps_200k_wfm_decim_1.taps, 131072); + decim_0.configure(taps_200k_wfm_decim_0.taps); + decim_1.configure(taps_200k_wfm_decim_1.taps); demod.configure(audio_fs, 5000); configured = true; diff --git a/firmware/baseband/proc_pocsag.cpp b/firmware/baseband/proc_pocsag.cpp index b80207e54..ebc3e0b92 100644 --- a/firmware/baseband/proc_pocsag.cpp +++ b/firmware/baseband/proc_pocsag.cpp @@ -107,8 +107,8 @@ void POCSAGProcessor::configure() { const size_t demod_input_fs = channel_filter_output_fs; - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); channel_filter.configure(taps_11k0_channel.taps, 2); demod.configure(demod_input_fs, 4'500); // FSK +/- 4k5Hz. diff --git a/firmware/baseband/proc_sonde.cpp b/firmware/baseband/proc_sonde.cpp index 391050080..1477c3573 100644 --- a/firmware/baseband/proc_sonde.cpp +++ b/firmware/baseband/proc_sonde.cpp @@ -29,8 +29,8 @@ #include "audio_output.hpp" SondeProcessor::SondeProcessor() { - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); audio_output.configure(false); diff --git a/firmware/baseband/proc_test.cpp b/firmware/baseband/proc_test.cpp index 648221a89..d2a857a70 100644 --- a/firmware/baseband/proc_test.cpp +++ b/firmware/baseband/proc_test.cpp @@ -27,8 +27,8 @@ #include "event_m4.hpp" TestProcessor::TestProcessor() { - decim_0.configure(taps_11k0_decim_0.taps, 33554432); - decim_1.configure(taps_11k0_decim_1.taps, 131072); + decim_0.configure(taps_11k0_decim_0.taps); + decim_1.configure(taps_11k0_decim_1.taps); baseband_thread.start(); } diff --git a/firmware/baseband/proc_tpms.cpp b/firmware/baseband/proc_tpms.cpp index ea6a28477..a7b3fca00 100644 --- a/firmware/baseband/proc_tpms.cpp +++ b/firmware/baseband/proc_tpms.cpp @@ -26,8 +26,8 @@ #include "event_m4.hpp" TPMSProcessor::TPMSProcessor() { - decim_0.configure(taps_200k_decim_0.taps, 33554432); - decim_1.configure(taps_200k_decim_1.taps, 131072); + decim_0.configure(taps_200k_decim_0.taps); + decim_1.configure(taps_200k_decim_1.taps); baseband_thread.start(); } diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index c1b1e58e1..f6a3cb39d 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -165,8 +165,8 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) { spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz; spectrum_samples = 0; - decim_0.configure(message.decim_0_filter.taps, 33554432); - decim_1.configure(message.decim_1_filter.taps, 131072); + decim_0.configure(message.decim_0_filter.taps); + decim_1.configure(message.decim_1_filter.taps); channel_filter_low_f = message.decim_1_filter.low_frequency_normalized * decim_1_input_fs; channel_filter_high_f = message.decim_1_filter.high_frequency_normalized * decim_1_input_fs; channel_filter_transition = message.decim_1_filter.transition_normalized * decim_1_input_fs; diff --git a/firmware/common/complex.hpp b/firmware/common/complex.hpp index e1bd2d714..ac24b0ab5 100644 --- a/firmware/common/complex.hpp +++ b/firmware/common/complex.hpp @@ -36,24 +36,12 @@ struct complex { typedef int8_t value_type; typedef uint16_t rep_type; - // constexpr complex( - // rep_type r - // ) : _rep { r } - // { - // } - constexpr complex( int8_t re = 0, int8_t im = 0) : _v{re, im} { } - // constexpr complex( - // const complex& o - // ) : _rep { o._rep } - // { - // } - constexpr int8_t real() const { return _v[0]; } constexpr int8_t imag() const { return _v[1]; } @@ -77,24 +65,12 @@ struct complex { typedef int16_t value_type; typedef uint32_t rep_type; - // constexpr complex( - // rep_type r - // ) : _rep { r } - // { - // } - constexpr complex( int16_t re = 0, int16_t im = 0) : _v{re, im} { } - // constexpr complex( - // const complex& o - // ) : _rep { o._rep } - // { - // } - constexpr int16_t real() const { return _v[0]; } constexpr int16_t imag() const { return _v[1]; }