Explain and clean up decimator scalars (#1422)

This commit is contained in:
Kyle Reed 2023-08-30 09:05:49 -07:00 committed by GitHub
parent 4bc752b7a8
commit f46e20c977
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 51 additions and 73 deletions

View File

@ -23,19 +23,26 @@
#define __DSP_DECIMATE_H__
#include <cstdint>
#include <algorithm>
#include <array>
#include <memory>
#include <algorithm>
#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<tap_t, taps_count>& 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<tap_t, taps_count>& 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<tap_t, taps_count>& 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<tap_t, taps_count>& taps,
const int32_t scale);
const int32_t scale = c16_to_c32_sat_scalar);
buffer_c16_t execute(
const buffer_c16_t& src,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps, decim_0_scale);
decim_0.set<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps);
decim_1.set<NoopDecim>();
break;
case OversampleRate::x8:
// M4 can't handle 2 decimation passes for sample rates <= 600k.
if (message.sample_rate < 600'000) {
decim_0.set<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps, decim_0_scale);
decim_1.set<FIRC16xR16x16Decim2>().configure(taps_200k_decim_1.taps, decim_1_scale);
decim_0.set<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps);
decim_1.set<FIRC16xR16x16Decim2>().configure(taps_200k_decim_1.taps);
} else {
// Using 180k taps to provide better filtering with a single pass.
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_180k_wfm_decim_0.taps, decim_0_scale);
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_180k_wfm_decim_0.taps);
decim_1.set<NoopDecim>();
}
break;
case OversampleRate::x16:
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_200k_decim_0.taps, decim_0_scale);
decim_1.set<FIRC16xR16x16Decim2>().configure(taps_200k_decim_1.taps, decim_1_scale);
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_200k_decim_0.taps);
decim_1.set<FIRC16xR16x16Decim2>().configure(taps_200k_decim_1.taps);
break;
case OversampleRate::x32:
decim_0.set<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps, decim_0_scale);
decim_1.set<FIRC16xR16x32Decim8>().configure(taps_16k0_decim_1.taps, decim_1_scale);
decim_0.set<FIRC8xR16x24FS4Decim4>().configure(taps_200k_decim_0.taps);
decim_1.set<FIRC16xR16x32Decim8>().configure(taps_16k0_decim_1.taps);
break;
case OversampleRate::x64:
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_200k_decim_0.taps, decim_0_scale);
decim_1.set<FIRC16xR16x32Decim8>().configure(taps_16k0_decim_1.taps, decim_1_scale);
decim_0.set<FIRC8xR16x24FS4Decim8>().configure(taps_200k_decim_0.taps);
decim_1.set<FIRC16xR16x32Decim8>().configure(taps_16k0_decim_1.taps);
break;
default:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,24 +36,12 @@ struct complex<int8_t> {
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<int16_t> {
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]; }