17 m_dirty.test_and_set(std::memory_order_release);
22 const bool is_glm = std::holds_alternative<std::vector<glm::vec2>>(variant)
23 || std::holds_alternative<std::vector<glm::vec3>>(variant)
24 || std::holds_alternative<std::vector<glm::vec4>>(variant)
25 || std::holds_alternative<std::vector<glm::mat4>>(variant);
32 const Eigen::Index total = mat.size();
33 m_pending.resize(
static_cast<size_t>(total));
35 Eigen::Map<Eigen::VectorXd>(
m_pending.data(), total) = Eigen::Map<const Eigen::VectorXd>(mat.data(), total);
39 m_pending.resize(
static_cast<size_t>(vec.size()));
40 Eigen::Map<Eigen::VectorXd>(
m_pending.data(), vec.size()) = vec;
43 m_dirty.test_and_set(std::memory_order_release);
49 std::ranges::transform(data,
m_pending.begin(),
50 [](
float s) { return static_cast<double>(s); });
51 m_dirty.test_and_set(std::memory_order_release);
56 m_pending.assign(data.begin(), data.end());
57 m_dirty.test_and_set(std::memory_order_release);
63 m_dirty.test_and_set(std::memory_order_release);
68 return m_dirty.test(std::memory_order_acquire);
77 if (!std::dynamic_pointer_cast<AudioBuffer>(buffer)) {
78 error<std::invalid_argument>(
81 std::source_location::current(),
82 "AudioWriteProcessor requires an AudioBuffer");
88 auto audio = std::dynamic_pointer_cast<AudioBuffer>(buffer);
91 "AudioWriteProcessor attached to non-AudioBuffer");
101 return std::dynamic_pointer_cast<AudioBuffer>(buffer) !=
nullptr;
110 if (
m_dirty.test(std::memory_order_acquire)) {
111 m_dirty.clear(std::memory_order_release);
119 const size_t dst_n = dst.size();
122 std::ranges::fill(dst, 0.0);
126 const size_t copy_n = std::min(dst_n,
m_active.size());
127 std::ranges::copy_n(
m_active.begin(),
static_cast<std::ptrdiff_t
>(copy_n), dst.begin());
129 if (copy_n < dst_n) {
130 std::fill(dst.begin() +
static_cast<std::ptrdiff_t
>(copy_n), dst.end(), 0.0);
#define MF_RT_ERROR(comp, ctx,...)
virtual std::vector< double > & get_data()
Gets mutable access to the buffer's underlying audio data.
Concrete audio implementation of the Buffer interface for double-precision audio data.
void write_to_buffer(AudioBuffer &buf) const
bool has_pending() const noexcept
Returns true if a snapshot has been set and not yet consumed.
std::vector< double > m_pending
void processing_function(const std::shared_ptr< Buffer > &buffer) override
The core processing function that must be implemented by derived classes.
bool is_compatible_with(const std::shared_ptr< Buffer > &buffer) const override
Checks if this processor can handle the specified buffer type.
void set_data(std::vector< double > data)
Supply the next frame of double-precision samples.
void clear()
Clear any pending snapshot.
void on_attach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is attached to a buffer.
std::vector< double > m_active
Eigen::VectorXd to_vector() const
Convert DataVariant to Eigen column vector.
Eigen::MatrixXd to_matrix() const
Convert DataVariant to Eigen matrix.
Type-erased accessor for converting DataVariant to Eigen types.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.