2026-03-02 17:23:14 +01:00
|
|
|
//
|
|
|
|
|
// Created by david on 02.03.2026.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "iir_filter.h"
|
2026-03-02 22:33:46 +01:00
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
#define DEBUG_IIR 0
|
|
|
|
|
|
|
|
|
|
#if (DEBUG_IIR == 1)
|
|
|
|
|
#define DEBUG_PRINT(expr) do { expr; } while (0)
|
|
|
|
|
#else
|
|
|
|
|
#define DEBUG_PRINT(expr) while(0) { expr; }
|
|
|
|
|
#endif
|
2026-03-02 17:23:14 +01:00
|
|
|
|
2026-03-11 20:47:53 +01:00
|
|
|
Buf::Buf(size_t N): N(N), n(0) {
|
2026-03-02 17:23:14 +01:00
|
|
|
data.resize(N);
|
|
|
|
|
data.assign(N, 0.0);
|
|
|
|
|
}
|
|
|
|
|
void Buf::push(double val) {
|
|
|
|
|
data[n] = val;
|
2026-03-11 20:47:53 +01:00
|
|
|
n = (n+1) % N;
|
2026-03-02 17:23:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Filt::Filt(size_t N, size_t shift, size_t offset, std::vector<double> taps): Buf(N), shift(shift), offset(offset), taps(taps) {
|
|
|
|
|
if (taps.size() != N) throw std::invalid_argument("taps.size() != N");
|
|
|
|
|
}
|
|
|
|
|
double Filt::filter(double val) {
|
|
|
|
|
this->push(val);
|
|
|
|
|
return this->peek();
|
|
|
|
|
}
|
|
|
|
|
double Filt::peek() {
|
|
|
|
|
double sum = 0;
|
2026-03-11 20:47:53 +01:00
|
|
|
for (size_t i = offset; i < this->N; i++) {
|
2026-03-02 17:23:14 +01:00
|
|
|
//size_t n = (this->n - i + shift - 1) % this->size; // unsigned % size ... bad if u is negative
|
2026-03-11 20:47:53 +01:00
|
|
|
size_t n = (this->N + this->n - i + shift - 1) % this->N;
|
2026-03-02 22:33:46 +01:00
|
|
|
DEBUG_PRINT(std::cout << " t[" << i << "] * v[" << n << "]" << std::endl);
|
2026-03-02 17:23:14 +01:00
|
|
|
sum += this->data[n] * this->taps[i];
|
|
|
|
|
}
|
|
|
|
|
return sum;
|
|
|
|
|
}
|
|
|
|
|
void Filt::push(double val) {
|
|
|
|
|
Buf::push(val);
|
|
|
|
|
}
|
2026-03-11 20:47:53 +01:00
|
|
|
void Filt::prime(double val) {
|
|
|
|
|
data.assign(this->N, val);
|
|
|
|
|
}
|
|
|
|
|
size_t Filt::size() {
|
|
|
|
|
return this->N;
|
|
|
|
|
}
|
2026-03-02 17:23:14 +01:00
|
|
|
|
|
|
|
|
IirFilter::IirFilter(std::vector<double> b, std::vector<double> a) : x(b.size(), 0, 0, b), y(a.size(), 1, 1, a) {
|
|
|
|
|
if (b.size() != a.size()) throw std::invalid_argument("b.size() != a.size()");
|
|
|
|
|
}
|
|
|
|
|
double IirFilter::filter(double val) {
|
2026-03-02 22:33:46 +01:00
|
|
|
DEBUG_PRINT(std::cout << "x.filter(" << val << ")" << std::endl);
|
2026-03-02 17:23:14 +01:00
|
|
|
double xv = x.filter(val);
|
2026-03-02 22:33:46 +01:00
|
|
|
DEBUG_PRINT(std::cout << "xv=" << xv << std::endl);
|
|
|
|
|
DEBUG_PRINT(std::cout << "y.peek()" << std::endl);
|
2026-03-02 17:23:14 +01:00
|
|
|
double yv = y.peek();
|
2026-03-02 22:33:46 +01:00
|
|
|
DEBUG_PRINT(std::cout << "yv=" << yv << std::endl);
|
|
|
|
|
DEBUG_PRINT(std::cout << "---" << std::endl);
|
2026-03-02 17:23:14 +01:00
|
|
|
double yo = xv - yv;
|
|
|
|
|
y.push(yo);
|
|
|
|
|
return yo;
|
|
|
|
|
}
|