FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
dsp_filters.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2007-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file dsp_filters.h
10 * @brief Header file for Digital Signal Processing (DSP) filters and upsampling/downsampling functionality.
11 */
12
13#pragma once
14
15#include <cstddef>
16#include <cstdint>
17#include <memory>
18#include <span>
19#include <vector>
20
21#include "core/config.h"
22
23namespace fers_signal
24{
25 /**
26 * @brief Upsamples a signal by a given ratio.
27 *
28 * @param in Input span of complex samples.
29 * @param size Size of the input signal.
30 * @param out Output span for upsampled complex samples.
31 * @throws std::invalid_argument if the input or output spans are empty or the ratio is zero.
32 */
33 void upsample(std::span<const ComplexType> in, unsigned size, std::span<ComplexType> out);
34
35 /**
36 * @brief Downsamples a signal by a given ratio.
37 *
38 * @param in Input span of complex samples.
39 * @throws std::invalid_argument if the input or output spans are empty or the ratio is zero.
40 */
41 std::vector<ComplexType> downsample(std::span<const ComplexType> in);
42
43 /**
44 * @class DownsamplingSink
45 * @brief Stateful FIR decimator for chunked streaming output.
46 *
47 * This sink uses the same Blackman-windowed FIR design as `downsample`, but keeps
48 * filter history across input blocks and only zero-pads when `finish()` is called.
49 */
51 {
52 public:
54
55 void consume(std::span<const ComplexType> block);
56 void finish();
57 [[nodiscard]] std::vector<ComplexType> takeOutput();
58 void reset();
59
60 [[nodiscard]] std::uint64_t inputSampleCount() const noexcept { return _input_sample_count; }
61 [[nodiscard]] std::uint64_t outputSampleCount() const noexcept { return _next_output_index; }
62 [[nodiscard]] unsigned ratio() const noexcept { return _ratio; }
63
64 private:
65 ComplexType processOne(ComplexType sample);
66 void maybeEmit(ComplexType filtered);
67
68 unsigned _ratio = 1;
69 std::vector<RealType> _coeffs;
70 std::vector<ComplexType> _line;
71 std::vector<ComplexType> _pending;
72 std::uint64_t _input_sample_count = 0;
73 std::uint64_t _processed_sample_count = 0;
74 std::uint64_t _next_output_index = 0;
75 std::uint64_t _target_output_count = 0;
76 std::size_t _delay = 0;
77 bool _finished = false;
78 };
79
80 /**
81 * @class DspFilter
82 * @brief Abstract base class for digital filters.
83 */
85 {
86 public:
87 DspFilter() = default;
88
89 virtual ~DspFilter() = default;
90
91 /**
92 * @brief Filters a single sample.
93 *
94 * @param sample A single real-valued sample to be filtered.
95 * @return The filtered sample.
96 */
97 virtual RealType filter(RealType sample) = 0;
98
99 /**
100 * @brief Filters a block of samples.
101 *
102 * @param samples Span of real-valued samples to be filtered.
103 */
104 virtual void filter(std::span<RealType> samples) = 0;
105
106 DspFilter(const DspFilter&) = delete;
107
108 DspFilter& operator=(const DspFilter&) = delete;
109
111
113 };
114
115 /**
116 * @class IirFilter
117 * @brief Implements an Infinite Impulse Response (IIR) filter.
118 */
120 {
121 public:
122 /**
123 * @brief Constructs an IIR filter with given numerator and denominator coefficients and order.
124 *
125 * @param denCoeffs Pointer to the denominator coefficients array.
126 * @param numCoeffs Pointer to the numerator coefficients array.
127 * @param order The order of the filter.
128 */
129 IirFilter(const RealType* denCoeffs, const RealType* numCoeffs, unsigned order) noexcept;
130
131 ~IirFilter() override = default;
132
133 /**
134 * @brief Filters a single sample.
135 *
136 * @param sample The sample to be filtered.
137 * @return The filtered sample.
138 */
139 RealType filter(RealType sample) noexcept override;
140
141 /**
142 * @brief Filters a block of samples.
143 *
144 * @param samples Span of samples to be filtered.
145 */
146 void filter(std::span<RealType> samples) noexcept override;
147
148 private:
149 std::vector<RealType> _a; ///< Denominator coefficients
150 std::vector<RealType> _b; ///< Numerator coefficients
151 std::vector<RealType> _w; ///< Internal state
152 unsigned _order{}; ///< Filter order
153 };
154
155 /**
156 * @class FirFilter
157 * @brief Implements a Finite Impulse Response (FIR) filter.
158 */
159 class FirFilter final : public DspFilter
160 {
161 public:
162 /**
163 * @brief Constructs an FIR filter with the given coefficients.
164 *
165 * @param coeffs Span of filter coefficients.
166 */
167 explicit FirFilter(std::span<const RealType> coeffs) :
168 _filter(coeffs.begin(), coeffs.end()), _w(coeffs.size()), _order(coeffs.size())
169 {
170 }
171
172 ~FirFilter() override = default;
173
174 /// Filters a single real-valued sample; FIR scalar filtering is unsupported.
175 RealType filter(RealType) override { return 0; }
176
177 /// Filters real-valued samples; FIR block filtering is unsupported for this overload.
178 void filter(std::span<RealType> /*samples*/) noexcept override {}
179
180 /**
181 * @brief Filters a block of complex samples.
182 *
183 * @param samples Span of complex samples to be filtered.
184 */
185 void filter(std::vector<ComplexType>& samples) const;
186
187 private:
188 std::vector<RealType> _filter; ///< Filter coefficients
189 std::vector<RealType> _w; ///< Internal state
190 std::size_t _order{}; ///< Filter order
191 };
192
193 /**
194 * @class DecadeUpsampler
195 * @brief Implements a specialized upsampler with a fixed upsampling factor of 10.
196 */
198 {
199 public:
201
202 ~DecadeUpsampler() = default;
203
204 /**
205 * @brief Upsamples a single sample.
206 *
207 * @param sample The sample to be upsampled.
208 * @param out Span of output samples.
209 */
210 void upsample(RealType sample, std::span<RealType> out) const;
211
213
215
217
219
220 private:
221 std::unique_ptr<IirFilter> _filter; ///< IIR filter for upsampling
222 };
223}
Implements a specialized upsampler with a fixed upsampling factor of 10.
DecadeUpsampler & operator=(const DecadeUpsampler &)=delete
DecadeUpsampler(const DecadeUpsampler &)=delete
DecadeUpsampler(DecadeUpsampler &&) noexcept=default
Stateful FIR decimator for chunked streaming output.
Definition dsp_filters.h:51
unsigned ratio() const noexcept
Definition dsp_filters.h:62
std::uint64_t inputSampleCount() const noexcept
Definition dsp_filters.h:60
std::uint64_t outputSampleCount() const noexcept
Definition dsp_filters.h:61
std::vector< ComplexType > takeOutput()
void consume(std::span< const ComplexType > block)
Abstract base class for digital filters.
Definition dsp_filters.h:85
DspFilter(const DspFilter &)=delete
DspFilter & operator=(const DspFilter &)=delete
virtual ~DspFilter()=default
DspFilter(DspFilter &&) noexcept=default
virtual void filter(std::span< RealType > samples)=0
Filters a block of samples.
virtual RealType filter(RealType sample)=0
Filters a single sample.
Implements a Finite Impulse Response (FIR) filter.
void filter(std::span< RealType >) noexcept override
Filters real-valued samples; FIR block filtering is unsupported for this overload.
~FirFilter() override=default
FirFilter(std::span< const RealType > coeffs)
Constructs an FIR filter with the given coefficients.
RealType filter(RealType) override
Filters a single real-valued sample; FIR scalar filtering is unsupported.
Implements an Infinite Impulse Response (IIR) filter.
~IirFilter() override=default
Global configuration file for the project.
double RealType
Type for real numbers.
Definition config.h:27
std::complex< RealType > ComplexType
Type for complex numbers.
Definition config.h:35
void upsample(const std::span< const ComplexType > in, const unsigned size, std::span< ComplexType > out)
Upsamples a complex waveform with zero-stuffing followed by Blackman FIR filtering.
std::vector< ComplexType > downsample(std::span< const ComplexType > in)
Low-pass filters and decimates an oversampled complex waveform back to base rate.
math::Vec3 max