MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BlockFeedbackProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6
7/**
8 * @class BlockFeedbackProcessor
9 * @brief Compares and transforms each whole block against an earlier block
10 *
11 * Where FeedbackProcessor works sample by sample, this works on the block as
12 * a unit: every cycle it hands a function the current block, the block from a
13 * set number of cycles ago and a coefficient array, and keeps what the
14 * function leaves in the buffer for later cycles. The function may rewrite
15 * the current block in place and returns one number, a feature of the block
16 * (a distance, a correlation, a level against the earlier one), which is
17 * stored per buffer and passed to an optional observer.
18 *
19 * State (retained blocks, coefficient array, last feature) is kept per
20 * attached buffer. Works on any AudioBuffer. Until enough cycles have passed
21 * the earlier block is zeros.
22 */
23class MAYAFLUX_API BlockFeedbackProcessor : public BufferProcessor {
24public:
25 /**
26 * @brief The per-block function
27 * @param current This cycle's block, free to rewrite
28 * @param previous The retained block from `lag_blocks` cycles ago
29 * @param coefficients This buffer's coefficient array, free to read and write
30 * @return A feature of the block
31 */
32 using Transform = std::function<double(std::span<double>, std::span<const double>, std::span<double>)>;
33
34 /**
35 * @param transform The per-block function
36 * @param lag_blocks How many cycles back the earlier block lies, minimum 1
37 * @param coefficients Initial coefficient array, copied to each attached buffer
38 */
39 BlockFeedbackProcessor(Transform transform, size_t lag_blocks = 1, std::vector<double> coefficients = {});
40
41 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
42 void on_attach(const std::shared_ptr<Buffer>& buffer) override;
43 void on_detach(const std::shared_ptr<Buffer>& buffer) override;
44 [[nodiscard]] bool is_compatible_with(const std::shared_ptr<Buffer>& buffer) const override;
45
46 /**
47 * @brief Keep the incoming block instead of the transformed one
48 * @param retain_input True retains what arrived, so the earlier block is
49 * the earlier input; false, the default, retains what the function
50 * left, so the earlier block is the earlier output
51 */
52 void set_retain_input(bool retain_input) { m_retain_input = retain_input; }
53
54 [[nodiscard]] bool get_retain_input() const { return m_retain_input; }
55
56 /**
57 * @brief Called with the feature after every block
58 */
59 void set_observer(std::function<void(double)> observer) { m_observer = std::move(observer); }
60
61 /**
62 * @brief The feature of the last block of one attached buffer, zero if none
63 */
64 [[nodiscard]] double feature(const std::shared_ptr<Buffer>& buffer) const;
65
66 /**
67 * @brief The coefficient array of one attached buffer, empty if it is not attached
68 */
69 [[nodiscard]] std::span<double> coefficients(const std::shared_ptr<Buffer>& buffer);
70
71 [[nodiscard]] size_t get_lag_blocks() const { return m_lag_blocks; }
72
73 /**
74 * @brief Same configuration, no attached state
75 */
76 [[nodiscard]] std::shared_ptr<BlockFeedbackProcessor> clone() const;
77
78private:
79 struct State {
80 std::vector<std::vector<double>> blocks;
81 std::vector<double> kept;
82 std::vector<double> coefs;
83 size_t next { 0 };
84 double feature { 0.0 };
85 };
86
88 size_t m_lag_blocks { 1 };
89 bool m_retain_input { false };
90 std::vector<double> m_coefficients;
91 std::function<void(double)> m_observer;
92
93 std::unordered_map<const Buffer*, State> m_states;
94};
95
96} // namespace MayaFlux::Buffers
std::shared_ptr< NetworkGeometryBuffer > buffer
std::unordered_map< const Buffer *, State > m_states
std::function< double(std::span< double >, std::span< const double >, std::span< double >)> Transform
The per-block function.
void set_observer(std::function< void(double)> observer)
Called with the feature after every block.
void set_retain_input(bool retain_input)
Keep the incoming block instead of the transformed one.
Compares and transforms each whole block against an earlier block.
Central computational transformation interface for continuous buffer processing.