55#include <TargetConditionals.h>
56#include <sys/sysctl.h>
61#if defined(PULP_SIMD_DEFAULT_BACKEND_ACCELERATE) && defined(__aarch64__) && \
62 defined(TARGET_OS_OSX) && TARGET_OS_OSX
63#define PULP_NON_UNIFORM_MEASURED_TABLE 1
65#define PULP_NON_UNIFORM_MEASURED_TABLE 0
79template <
typename SampleType =
float>
117#if PULP_NON_UNIFORM_MEASURED_TABLE
118 if constexpr (!std::is_same_v<SampleType, float>) {
124 constexpr std::array<std::uint64_t, 4> kMeasuredIr{4096, 16384, 48000, 96000};
125 std::size_t column = 0;
126 const auto n =
static_cast<std::uint64_t
>(ir_length);
127 while (column + 1 < kMeasuredIr.size() &&
128 n * n > kMeasuredIr[column] * kMeasuredIr[column + 1])
132 return std::array<std::size_t, 4>{16, 32, 64, 64}[column];
134 return std::array<std::size_t, 4>{8, 16, 32, 64}[column];
136 return std::array<std::size_t, 4>{8, 16, 16, 32}[column];
138 return std::array<std::size_t, 4>{8, 8, 16, 32}[column];
140 return std::array<std::size_t, 4>{4, 8, 16, 16}[column];
142 return std::array<std::size_t, 4>{8, 8, 8, 16}[column];
160 for (
const std::string_view family :
161 {std::string_view{
"Apple M1"}, std::string_view{
"Apple M5"}}) {
162 if (cpu_brand.substr(0, family.size()) != family)
164 if (cpu_brand.size() == family.size() || cpu_brand[family.size()] ==
' ')
175 std::size_t ir_length,
187#if PULP_NON_UNIFORM_MEASURED_TABLE
188 static const bool measured = [] {
189 char brand[128] = {};
190 std::size_t size =
sizeof(brand) - 1;
191 if (sysctlbyname(
"machdep.cpu.brand_string", brand, &size,
nullptr, 0) != 0)
233 if (ir ==
nullptr || ir_length == 0 ||
block_size == 0)
return;
242 std::size_t
head_samples = tail_multiplier_ * block_size_;
251 std::size_t
tail_block = block_size_ * tail_multiplier_;
257 tail_ir_slice_.assign(ir +
head_samples, ir + ir_length);
258 tail_.load_ir(tail_ir_slice_.data(), tail_len,
tail_block);
261 tail_input_buf_.assign(tail_block_, SampleType{0.0f});
262 tail_output_buf_.assign(tail_block_, SampleType{0.0f});
264 tail_stream_pos_ = tail_block_;
298 std::size_t num_samples) {
302 std::copy_n(input, num_samples, output);
306 if (num_samples != block_size_) {
307 std::fill_n(output, num_samples, SampleType{0.0f});
308 ++block_size_violations_;
309 history_torn_ =
true;
313 if (history_torn_)
reset();
318 if (tail_block_ > 0) {
319 std::copy_n(input, block_size_, tail_input_buf_.data() + tail_fill_);
320 tail_fill_ += block_size_;
324 head_.process(input, output, num_samples);
326 if (tail_block_ == 0)
return;
329 if (tail_stream_pos_ < tail_block_) {
330 for (std::size_t
i = 0;
i < block_size_; ++
i)
331 output[
i] += tail_output_buf_[tail_stream_pos_ +
i];
332 tail_stream_pos_ += block_size_;
335 if (tail_fill_ >= tail_block_) {
339 tail_.process(tail_input_buf_.data(),
340 tail_output_buf_.data(), tail_block_);
342 tail_stream_pos_ = 0;
348 if (tail_block_ > 0) tail_.reset();
349 std::fill(tail_input_buf_.begin(), tail_input_buf_.end(), SampleType{0.0f});
350 std::fill(tail_output_buf_.begin(), tail_output_buf_.end(), SampleType{0.0f});
352 tail_stream_pos_ = tail_block_;
353 history_torn_ =
false;
354 block_size_violations_ = 0;
377 static std::size_t round_up_pow2(std::size_t v) {
378 if (v <= 1)
return 1;
379 if ((v & (v - 1)) == 0)
return v;
381 while (p < v) p <<= 1;
386 head_ = PartitionedConvolverT<SampleType>{};
387 tail_ = PartitionedConvolverT<SampleType>{};
388 tail_ir_slice_.clear();
389 tail_input_buf_.clear();
390 tail_output_buf_.clear();
393 tail_multiplier_ = 0;
396 tail_stream_pos_ = 0;
400 PartitionedConvolverT<SampleType> head_;
401 PartitionedConvolverT<SampleType> tail_;
402 std::vector<SampleType> tail_ir_slice_;
403 std::vector<SampleType> tail_input_buf_;
404 std::vector<SampleType> tail_output_buf_;
405 std::size_t block_size_ = 0;
406 std::size_t tail_block_ = 0;
407 std::size_t tail_multiplier_ = 0;
408 std::size_t head_samples_ = 0;
409 std::size_t tail_fill_ = 0;
410 std::size_t tail_stream_pos_ = 0;
411 bool loaded_ =
false;
415 bool history_torn_ =
false;
416 std::uint64_t block_size_violations_ = 0;
constexpr std::size_t convolver_block_size(std::size_t block_size) noexcept
The block size a convolver prepared for block_size accepts: the request rounded up to the next power ...
Definition convolver_messages.hpp:188
Definition additive_bank.hpp:218
NonUniformPartitionedConvolverT< float > NonUniformPartitionedConvolver
Definition convolver_non_uniform.hpp:419
@ i
Definition formant_filter_bank.hpp:20
NonUniformPartitionedConvolverT< double > NonUniformPartitionedConvolver64
Definition convolver_non_uniform.hpp:420