Skip to content

Commit

Permalink
DSP refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
dancazarin committed Feb 5, 2024
1 parent 22d5a24 commit f1ac648
Show file tree
Hide file tree
Showing 14 changed files with 634 additions and 233 deletions.
63 changes: 28 additions & 35 deletions examples/iir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,91 +14,84 @@ int main()
{
println(library_version());

constexpr size_t maxorder = 32;

const std::string options = "phaseresp=True, log_freq=True, freq_dB_lim=(-160, 10), padwidth=8192";

univector<fbase, 1024> output;
{
zpk<fbase> filt = iir_lowpass(bessel<fbase>(24), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(bessel<fbase>(24), 1000, 48000);
output = iir(unitimpulse(), filt);
}
plot_save("bessel_lowpass24", output, options + ", title='24th-order Bessel filter, lowpass 1khz'");

{
zpk<fbase> filt = iir_lowpass(bessel<fbase>(12), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(bessel<fbase>(12), 1000, 48000);
output = iir(unitimpulse(), filt);
}
plot_save("bessel_lowpass12", output, options + ", title='12th-order Bessel filter, lowpass 1khz'");

{
zpk<fbase> filt = iir_lowpass(bessel<fbase>(6), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(bessel<fbase>(6), 1000, 48000);
output = iir(unitimpulse(), filt);
}
plot_save("bessel_lowpass6", output, options + ", title='6th-order Bessel filter, lowpass 1khz'");

{
zpk<fbase> filt = iir_lowpass(butterworth<fbase>(24), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(butterworth<fbase>(24), 1000, 48000);
output = iir(unitimpulse(), filt);
}
plot_save("butterworth_lowpass24", output,
options + ", title='24th-order Butterworth filter, lowpass 1khz'");

{
zpk<fbase> filt = iir_lowpass(butterworth<fbase>(12), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(butterworth<fbase>(12), 1000, 48000);
output = iir(unitimpulse(), filt);
}
plot_save("butterworth_lowpass12", output,
options + ", title='12th-order Butterworth filter, lowpass 1khz'");

{
zpk<fbase> filt = iir_highpass(butterworth<fbase>(12), 1000, 48000);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_highpass(butterworth<fbase>(12), 1000, 48000);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), bqs);
}
plot_save("butterworth_highpass12", output,
options + ", title='12th-order Butterworth filter, highpass 1khz'");

{
zpk<fbase> filt = iir_bandpass(butterworth<fbase>(12), 0.1, 0.2);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_bandpass(butterworth<fbase>(12), 0.1, 0.2);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), bqs);
}
plot_save("butterworth_bandpass12", output,
options + ", title='12th-order Butterworth filter, bandpass'");

{
zpk<fbase> filt = iir_bandstop(butterworth<fbase>(12), 0.1, 0.2);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_bandstop(butterworth<fbase>(12), 0.1, 0.2);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), bqs);
}
plot_save("butterworth_bandstop12", output,
options + ", title='12th-order Butterworth filter, bandstop'");

{
zpk<fbase> filt = iir_bandpass(butterworth<fbase>(4), 0.005, 0.9);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_bandpass(butterworth<fbase>(4), 0.005, 0.9);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), bqs);
}
plot_save("butterworth_bandpass4", output, options + ", title='4th-order Butterworth filter, bandpass'");

{
zpk<fbase> filt = iir_lowpass(chebyshev1<fbase>(8, 2), 0.09);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(chebyshev1<fbase>(8, 2), 0.09);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), bqs);
}
plot_save("chebyshev1_lowpass8", output,
options + ", title='8th-order Chebyshev type I filter, lowpass'");

{
zpk<fbase> filt = iir_lowpass(chebyshev2<fbase>(8, 80), 0.09);
std::vector<biquad_params<fbase>> bqs = to_sos(filt);
output = biquad<maxorder>(bqs, unitimpulse());
zpk<fbase> filt = iir_lowpass(chebyshev2<fbase>(8, 80), 0.09);
iir_params<fbase> bqs = to_sos(filt); // to_sos is expensive, keep iir_params if reused
output = iir(unitimpulse(), filt);
}
plot_save("chebyshev2_lowpass8", output,
options + ", title='8th-order Chebyshev type II filter, lowpass'");
Expand Down
44 changes: 31 additions & 13 deletions include/kfr/base/state_holder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ namespace kfr
{

template <typename T, bool Stateless>
struct state_holder
struct state_holder;

template <typename T>
struct state_holder<T, false>
{
static_assert(!std::is_const_v<T>, "state_holder: T must not be const");

constexpr state_holder() = delete;
constexpr state_holder(const state_holder&) = default;
constexpr state_holder(state_holder&&) = default;
constexpr state_holder(const T& state) CMT_NOEXCEPT : s(state) {}
constexpr state_holder(std::reference_wrapper<const T> state) CMT_NOEXCEPT : s(state) {}
constexpr state_holder(T state) CMT_NOEXCEPT : s(std::move(state)) {}
constexpr state_holder(std::reference_wrapper<T> state) = delete;
constexpr state_holder(std::reference_wrapper<const T> state) = delete;
constexpr state_holder(state_holder<T, true> stateless) : s(*stateless) {}
T s;

const T* operator->() const { return &s; }
Expand All @@ -33,17 +40,28 @@ struct state_holder
template <typename T>
struct state_holder<T, true>
{
constexpr state_holder() = delete;
constexpr state_holder(const state_holder&) = default;
constexpr state_holder(state_holder&&) = default;
constexpr state_holder(T& state) CMT_NOEXCEPT : s(state) {}
constexpr state_holder(std::reference_wrapper<T> state) CMT_NOEXCEPT : s(state) {}
T& s;
static_assert(!std::is_const_v<T>, "state_holder: T must not be const");

constexpr state_holder() = delete;
constexpr state_holder(const state_holder&) = default;
constexpr state_holder(state_holder&&) = default;
constexpr state_holder(T state) CMT_NOEXCEPT = delete;
constexpr state_holder(const T& state) CMT_NOEXCEPT = delete;
constexpr state_holder(T& state) CMT_NOEXCEPT = delete;
constexpr state_holder(T&& state) CMT_NOEXCEPT = delete;
constexpr state_holder(std::reference_wrapper<T> state) CMT_NOEXCEPT : s(&state.get()) {}
T* s;

const T* operator->() const { return &s; }
T* operator->() { return &s; }
const T& operator*() const { return s; }
T& operator*() { return s; }
const T* operator->() const { return s; }
T* operator->() { return s; }
const T& operator*() const { return *s; }
T& operator*() { return *s; }
};

static_assert(std::is_copy_constructible_v<state_holder<float, true>>);
static_assert(std::is_copy_constructible_v<state_holder<float, false>>);

static_assert(std::is_move_constructible_v<state_holder<float, true>>);
static_assert(std::is_move_constructible_v<state_holder<float, false>>);

} // namespace kfr
15 changes: 13 additions & 2 deletions include/kfr/cometa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,18 @@ struct has_data_size_impl<T,
{
};

template <typename, typename = void>
struct has_data_size_free_impl : std::false_type
{
};

template <typename T>
struct has_data_size_free_impl<
T, std::void_t<decltype(std::size(std::declval<T>())), decltype(std::data(std::declval<T>()))>>
: std::true_type
{
};

template <typename, typename Fallback, typename = void>
struct value_type_impl
{
Expand All @@ -1453,8 +1465,7 @@ template <typename T>
constexpr inline bool has_data_size = details::has_data_size_impl<std::decay_t<T>>::value;

#define CMT_HAS_DATA_SIZE(CONTAINER) \
std::void_t<decltype(std::size(std::declval<CONTAINER>())), \
decltype(std::data(std::declval<CONTAINER>()))>* = nullptr
std::enable_if_t<details::has_data_size_free_impl<CONTAINER>::value>* = nullptr

template <typename T>
using value_type_of = typename std::decay_t<T>::value_type;
Expand Down
Loading

0 comments on commit f1ac648

Please sign in to comment.