1#ifndef CONSTFILT_ANALOG_FILTER_HPP
2#define CONSTFILT_ANALOG_FILTER_HPP
4#include "discretize.hpp"
6#include "stability.hpp"
55template <
typename T, consteig::Size N,
typename Method = TustinNW,
56 bool CheckStab =
true>
57class AnalogFilter :
public Filter<T, N + 1u, N + 1u>
59 static_assert(N >= 1u,
"Filter order must be at least 1");
61 using BoundMethod =
typename bind_method<T, Method>::type;
64 constexpr AnalogFilter(
const T (&b_c)[N + 1u],
const T (&a_c)[N + 1u],
67 checked_discretize(b_c, a_c, sample_rate_hz, BoundMethod{}))
69 static_assert(!is_tustinpw_tag<Method>::value,
70 "TustinPW requires a warp frequency; use the "
71 "method-tag constructor with constfilt::prewarp(wc_hz)");
74 constexpr AnalogFilter(
const T (&b_c)[N + 1u],
const T (&a_c)[N + 1u],
75 T sample_rate_hz, BoundMethod method_tag)
76 : AnalogFilter(checked_discretize(b_c, a_c, sample_rate_hz, method_tag))
80 constexpr AnalogFilter(TransferFunction<T, N + 1u, N + 1u> continuous_tf,
82 : AnalogFilter(checked_discretize(continuous_tf.b, continuous_tf.a,
83 sample_rate_hz, BoundMethod{}))
85 static_assert(!is_tustinpw_tag<Method>::value,
86 "TustinPW requires a warp frequency; use the "
87 "method-tag constructor with constfilt::prewarp(wc_hz)");
90 constexpr AnalogFilter(TransferFunction<T, N + 1u, N + 1u> continuous_tf,
91 T sample_rate_hz, BoundMethod method_tag)
92 : AnalogFilter(checked_discretize(continuous_tf.b, continuous_tf.a,
93 sample_rate_hz, method_tag))
97 constexpr AnalogFilter(TransferFunction<T, N + 1u, N + 1u> continuous_tf,
98 const FactoredTF<T, N> &factored_tf,
99 T sample_rate_hz, BoundMethod method_tag)
100 : AnalogFilter(checked_discretize_factored(continuous_tf.b,
101 continuous_tf.a, factored_tf,
102 sample_rate_hz, method_tag))
107 constexpr explicit AnalogFilter(
108 TransferFunction<T, N + 1u, N + 1u> digital_tf)
109 : Filter<T, N + 1u, N + 1u>(digital_tf.b, digital_tf.a)
113 static constexpr TransferFunction<T, N + 1u, N + 1u> checked_discretize(
114 const T (&b_c)[N + 1u],
const T (&a_c)[N + 1u], T sample_rate_hz,
115 BoundMethod method_tag)
144 return analog_to_digital<T, N>(
145 b_c, a_c,
static_cast<T
>(1) / sample_rate_hz, method_tag);
148 static constexpr TransferFunction<T, N + 1u, N + 1u>
149 checked_discretize_factored(
const T (&b_c)[N + 1u],
const T (&a_c)[N + 1u],
150 const FactoredTF<T, N> &factored_tf,
151 T sample_rate_hz, BoundMethod method_tag)
153 return discretize_with_factored<T, N>(
154 b_c, a_c, factored_tf,
static_cast<T
>(1) / sample_rate_hz,