10#ifndef DSY_FIRFILTER_H
11#define DSY_FIRFILTER_H
30#define FIRFILTER_USER_MEMORY 0, 0
40template <
size_t max_size,
size_t max_block>
46 void Reset() { memset(state_, 0, state_size_ *
sizeof(state_[0])); }
50 FIRMemory() : state_{0}, coefs_{0}, size_(0) {}
53 static constexpr size_t MaxBlock() {
return max_block; }
61 bool SetCoefs(
const float coefs[],
size_t size,
bool reverse)
64 size_ = DSY_MIN(size, max_size);
69 for(
size_t i = 0; i < size_; i++)
72 coefs_[i] = coefs[size - 1u - i];
78 memcpy(coefs_, coefs, size_ *
sizeof(coefs[0]));
84 static constexpr size_t state_size_ = max_size + max_block - 1u;
85 float state_[state_size_];
86 float coefs_[max_size];
105 state_size_ = length;
110 assert(
nullptr != state_);
111 assert(0 != state_size_);
112 if(
nullptr != state_)
114 memset(state_, 0, state_size_ *
sizeof(state_[0]));
119 FIRMemory() : state_(nullptr), coefs_(nullptr), size_(0), state_size_(0) {}
122 size_t MaxBlock()
const
124 return state_size_ + 1u > size_ ? state_size_ + 1u - size_ : 0;
133 bool SetCoefs(
const float coefs[],
size_t size,
bool reverse)
136 assert(
false == reverse);
137 assert(
nullptr != coefs || 0 == size);
139 if(
false == reverse && (
nullptr != coefs || 0 == size))
166template <
size_t max_size,
size_t max_block>
180 static constexpr size_t GetLatency() {
return 0; }
187 state_[size_ - 1u] = in;
191 for(
size_t i = 0; i < size_ - 1; i++)
193 acc += state_[i] * coefs_[i];
197 state_[i] = state_[1 + i];
199 acc += in * coefs_[size_ - 1u];
205 void ProcessBlock(
const float* pSrc,
float* pDst,
size_t block)
208 assert(block <= FIRMem::MaxBlock());
210 assert(
nullptr != pSrc);
211 assert(
nullptr != pDst);
214 for(
size_t j = 0; j < block; j++)
217 state_[size_ - 1u + j] = pSrc[j];
221 for(
size_t i = 0; i < size_; i++)
223 acc += state_[j + i] * coefs_[i];
231 for(
size_t i = 0; i < size_ - 1u; i++)
233 state_[i] = state_[block + i];
242 bool SetIR(
const float* ir,
size_t len,
bool reverse)
251 template <
typename... Args>
252 inline auto Init(Args&&... args)
253 ->
decltype(
SetIR(std::forward<Args>(args)...))
255 return SetIR(std::forward<Args>(args)...);
260 using FIRMem::coefs_;
262 using FIRMem::state_;
266#if(defined(USE_ARM_DSP) && defined(__arm__))
275template <
size_t max_size,
size_t max_block>
276class FIRFilterImplARM :
public FIRMemory<max_size, max_block>
279 using FIRMem = FIRMemory<max_size, max_block>;
283 FIRFilterImplARM() : fir_{0} {}
289 static constexpr size_t GetLatency() {
return 0; }
292 float Process(
float in)
295 arm_fir_f32(&fir_, &in, &out, 1);
300 void ProcessBlock(
float* pSrc,
float* pDst,
size_t block)
302 assert(block <= FIRMem::MaxBlock());
303 arm_fir_f32(&fir_, pSrc, pDst, block);
311 bool SetIR(
const float* ir,
size_t len,
bool reverse)
314 const bool result = FIRMem::SetCoefs(ir, len, reverse);
315 arm_fir_init_f32(&fir_, len, (
float*)coefs_, state_, max_block);
320 template <
typename... Args>
321 inline auto Init(Args&&... args)
322 ->
decltype(SetIR(std::forward<Args>(args)...))
324 return SetIR(std::forward<Args>(args)...);
328 arm_fir_instance_f32 fir_;
329 using FIRMem::coefs_;
331 using FIRMem::state_;
336template <
size_t max_size,
size_t max_block>
337using FIR = FIRFilterImplARM<max_size, max_block>;
343template <
size_t max_size,
size_t max_block>
344using FIR = FIRFilterImplGeneric<max_size, max_block>;
bool SetIR(const float *ir, size_t len, bool reverse)
Definition fir.h:242
float Process(float in)
Definition fir.h:183
FIR Filter implementation, generic and ARM CMSIS DSP based.
Definition adenv.h:16
bool SetCoefs(const float coefs[], size_t size, bool reverse)
Definition fir.h:133
void SetStateBuffer(float state[], size_t length)
Definition fir.h:102
bool SetCoefs(const float coefs[], size_t size, bool reverse)
Definition fir.h:61