Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
denormal.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <cstddef>
5#include <cstdint>
6
7namespace pulp::signal {
8
28#ifndef PULP_DSP_ENABLE_SNAP_TO_ZERO
29#define PULP_DSP_ENABLE_SNAP_TO_ZERO 1
30#endif
31
35template<typename T>
36inline constexpr T snap_threshold() { return T(1e-15); }
37
44template<typename T>
45inline T snap_to_zero(T x) {
46#if PULP_DSP_ENABLE_SNAP_TO_ZERO
47 // One comparison on |x| rather than two joined by &&: the same result for
48 // every input (NaN fails it and passes through; -0 becomes +0 as before),
49 // and no short-circuit for a compiler to turn into control flow, which
50 // keeps loops that snap vectorizable under GCC.
51 return std::abs(x) < snap_threshold<T>() ? T(0) : x;
52#else
53 return x;
54#endif
55}
56
74inline constexpr bool kSubnormalsAreFree =
75#if defined(__aarch64__) || defined(_M_ARM64)
76 true;
77#else
78 false;
79#endif
80
84template <typename T> inline T snap_recursion_state(T x) {
85 if constexpr (kSubnormalsAreFree)
86 return x;
87 else
88 return snap_to_zero(x);
89}
90
92template<typename T>
93inline void snap_to_zero(T* samples, int n) {
94#if PULP_DSP_ENABLE_SNAP_TO_ZERO
95 for (int i = 0; i < n; ++i)
96 samples[i] = snap_to_zero(samples[i]);
97#else
98 (void) samples;
99 (void) n;
100#endif
101}
102
113inline constexpr std::size_t kSnapChunkSamples = 64;
114
116struct SnapChunk {
117 std::size_t begin;
118 std::size_t end;
119};
120
138 public:
139 explicit constexpr SnapChunks(std::size_t num_samples) noexcept : size_(num_samples) {}
140
141 class iterator {
142 public:
143 constexpr iterator(std::size_t begin, std::size_t size) noexcept
144 : begin_(begin), size_(size) {}
145 constexpr SnapChunk operator*() const noexcept {
146 return {begin_,
147 size_ - begin_ < kSnapChunkSamples ? size_ : begin_ + kSnapChunkSamples};
148 }
149 constexpr iterator& operator++() noexcept {
150 begin_ = size_ - begin_ < kSnapChunkSamples ? size_ : begin_ + kSnapChunkSamples;
151 return *this;
152 }
153 constexpr bool operator!=(const iterator& other) const noexcept {
154 return begin_ != other.begin_;
155 }
156
157 private:
158 std::size_t begin_;
159 std::size_t size_;
160 };
161
162 constexpr iterator begin() const noexcept {
163 return {0, size_};
164 }
165 constexpr iterator end() const noexcept {
166 return {size_, size_};
167 }
168
169 private:
170 std::size_t size_;
171};
172
173constexpr SnapChunks snap_chunks(std::size_t num_samples) noexcept {
174 return SnapChunks(num_samples);
175}
176
179template<typename T>
180inline bool is_denormal(T x) {
181 return x != T(0) && std::fpclassify(x) == FP_SUBNORMAL;
182}
183
184} // namespace pulp::signal
Definition denormal.hpp:141
constexpr iterator & operator++() noexcept
Definition denormal.hpp:149
constexpr bool operator!=(const iterator &other) const noexcept
Definition denormal.hpp:153
constexpr iterator(std::size_t begin, std::size_t size) noexcept
Definition denormal.hpp:143
constexpr SnapChunk operator*() const noexcept
Definition denormal.hpp:145
The chunks of [0, num_samples), consecutive and at most kSnapChunkSamples long, as a range.
Definition denormal.hpp:137
constexpr SnapChunks(std::size_t num_samples) noexcept
Definition denormal.hpp:139
constexpr iterator end() const noexcept
Definition denormal.hpp:165
constexpr iterator begin() const noexcept
Definition denormal.hpp:162
Definition additive_bank.hpp:218
constexpr T snap_threshold()
Threshold in absolute value below which a sample is treated as zero.
Definition denormal.hpp:36
constexpr std::size_t kSnapChunkSamples
Samples a block path runs between denormal snaps of its recursive state.
Definition denormal.hpp:113
constexpr bool kSubnormalsAreFree
Whether subnormal arithmetic runs at full speed on this target.
Definition denormal.hpp:74
T snap_to_zero(T x)
Returns 0 if |x| < snap_threshold, else x.
Definition denormal.hpp:45
@ i
Definition formant_filter_bank.hpp:20
@ e
Definition formant_filter_bank.hpp:20
bool is_denormal(T x)
Return true if x is a denormal (subnormal) float.
Definition denormal.hpp:180
constexpr SnapChunks snap_chunks(std::size_t num_samples) noexcept
Definition denormal.hpp:173
T snap_recursion_state(T x)
Snap a per-sample recursion's state: snap_to_zero() where subnormals are slow, the identity where kSu...
Definition denormal.hpp:84
One chunk of a block: samples [begin, end).
Definition denormal.hpp:116
std::size_t end
Definition denormal.hpp:118
std::size_t begin
Definition denormal.hpp:117