MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Counter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Generator.hpp"
4
6
7/**
8 * @class Counter
9 * @brief Integer step accumulator with modulo wrap and optional trigger reset
10 *
11 * Advances an internal integer counter by a fixed step on every process_sample()
12 * call, wrapping at a configurable modulo boundary. Output is the counter value
13 * normalized to [0, 1] by default, making it directly composable with any
14 * downstream node expecting a unit-range signal.
15 *
16 * When modulo is zero the counter accumulates without bound and the raw integer
17 * value is emitted as a double, suitable for use as a direct index.
18 *
19 * An optional reset trigger node resets the counter to zero on a rising edge
20 * (transition from zero to nonzero). The trigger is edge-sensitive: a sustained
21 * nonzero value does not repeatedly reset.
22 *
23 * Tick rate is determined entirely by the processing token the node is routed
24 * into (AUDIO_RATE or VISUAL_RATE), consistent with all other generators.
25 */
26class MAYAFLUX_API Counter : public Generator, public std::enable_shared_from_this<Counter> {
27public:
28 /**
29 * @brief Construct with modulo and step
30 * @param modulo Wrap boundary (0 = unbounded)
31 * @param step Increment per tick (negative for countdown)
32 */
33 Counter(uint32_t modulo = 16, int32_t step = 1);
34
35 /**
36 * @brief Construct with reset trigger node
37 * @param reset_trigger Node whose rising edge resets the counter
38 * @param modulo Wrap boundary (0 = unbounded)
39 * @param step Increment per tick (negative for countdown)
40 */
41 Counter(const std::shared_ptr<Node>& reset_trigger, uint32_t modulo = 16, int32_t step = 1);
42
43 ~Counter() override = default;
44
45 double process_sample(double input = 0.0) override;
46
47 std::vector<double> process_batch(unsigned int num_samples) override;
48
49 /**
50 * @brief Sets the wrap boundary
51 * @param modulo New modulo value (0 = unbounded)
52 */
53 void set_modulo(uint32_t modulo);
54
55 /**
56 * @brief Sets the step increment
57 * @param step Signed step value applied each tick
58 */
59 void set_step(int32_t step);
60
61 /**
62 * @brief Connects a reset trigger node
63 * @param trigger Node whose rising edge resets the counter to zero
64 */
65 void set_reset_trigger(const std::shared_ptr<Node>& trigger);
66
67 /**
68 * @brief Disconnects the reset trigger node
69 */
70 void clear_reset_trigger();
71
72 /**
73 * @brief Resets counter to zero immediately
74 */
75 void reset();
76
77 /** @brief Returns current raw counter value */
78 [[nodiscard]] uint32_t get_count() const { return m_count; }
79
80 /** @brief Returns current modulo */
81 [[nodiscard]] uint32_t get_modulo() const { return m_modulo; }
82
83 /** @brief Returns current step */
84 [[nodiscard]] int32_t get_step() const { return m_step; }
85
86 /**
87 * @brief Registers a callback fired on every increment
88 * @param callback Receives GeneratorContext directly; phase field carries the raw count
89 */
90 void on_increment(const TypedHook<GeneratorContext>& callback);
91
92 /**
93 * @brief Registers a callback fired when the counter wraps to zero
94 * @param callback Receives GeneratorContext at the wrap boundary
95 */
96 void on_wrap(const TypedHook<GeneratorContext>& callback);
97
98 /**
99 * @brief Registers a callback fired when the counter reaches a specific raw value
100 * @param target Raw counter value to match
101 * @param callback Receives GeneratorContext when count == target
102 */
103 void on_count(uint32_t target, const TypedHook<GeneratorContext>& callback);
104
105 bool remove_hook(const NodeHook& callback) override;
106 void remove_all_hooks() override;
107
108 void set_frequency(float) override { }
109 [[nodiscard]] float get_frequency() const { return 0.F; }
110
111 void save_state() override;
112 void restore_state() override;
113
114 /**
115 * @brief Retrieves the current modulators connected to this node
116 * @return Vector of pairs containing the modulator role and the corresponding node
117 */
118 [[nodiscard]] std::vector<std::pair<ModulatorRole, std::shared_ptr<Node>>> get_modulators() const override;
119
120protected:
121 void notify_tick(double value) override;
122 void update_context(double value) override;
123
124private:
125 uint32_t m_count { 0 };
126 uint32_t m_modulo { 16 };
127 int32_t m_step { 1 };
128
129 std::shared_ptr<Node> m_reset_trigger;
130 double m_last_trigger_value { 0.0 };
131
132 uint32_t m_saved_count { 0 };
133 double m_saved_last_trigger_value { 0.0 };
134 double m_saved_last_output { 0.0 };
135
136 bool m_wrapped { false };
137
138 std::vector<TypedHook<GeneratorContext>> m_increment_callbacks;
139 std::vector<TypedHook<GeneratorContext>> m_wrap_callbacks;
140 std::vector<std::pair<uint32_t, TypedHook<GeneratorContext>>> m_count_callbacks;
141};
142
143} // namespace MayaFlux::Nodes::Generator
Core::GlobalInputConfig input
Definition Config.cpp:36
void set_frequency(float) override
Sets the generator's frequency.
Definition Counter.hpp:108
std::vector< TypedHook< GeneratorContext > > m_increment_callbacks
Definition Counter.hpp:138
float get_frequency() const
Gets the current frequency.
Definition Counter.hpp:109
uint32_t get_modulo() const
Returns current modulo.
Definition Counter.hpp:81
int32_t get_step() const
Returns current step.
Definition Counter.hpp:84
std::vector< TypedHook< GeneratorContext > > m_wrap_callbacks
Definition Counter.hpp:139
std::vector< std::pair< uint32_t, TypedHook< GeneratorContext > > > m_count_callbacks
Definition Counter.hpp:140
std::shared_ptr< Node > m_reset_trigger
Definition Counter.hpp:129
uint32_t get_count() const
Returns current raw counter value.
Definition Counter.hpp:78
Integer step accumulator with modulo wrap and optional trigger reset.
Definition Counter.hpp:26
Base class for all signal and pattern generators in Maya Flux.
TypedHook<> NodeHook
Alias for TypedHook<NodeContext>.
Definition NodeUtils.hpp:38
std::function< void(ContextT &)> TypedHook
Callback function type for node processing events, parameterised on context type.
Definition NodeUtils.hpp:28