MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Counter.cpp
Go to the documentation of this file.
1#include "Counter.hpp"
2
4
5Counter::Counter(uint32_t modulo, int32_t step)
6 : m_modulo(modulo)
7 , m_step(step)
8{
9 m_amplitude = 1.0;
10 m_frequency = 0.F;
11}
12
13Counter::Counter(const std::shared_ptr<Node>& reset_trigger, uint32_t modulo, int32_t step)
14 : m_modulo(modulo)
15 , m_step(step)
16 , m_reset_trigger(reset_trigger)
17{
18 m_amplitude = 1.0;
19 m_frequency = 0.F;
20}
21
22void Counter::set_modulo(uint32_t modulo) { m_modulo = modulo; }
23void Counter::set_step(int32_t step) { m_step = step; }
24void Counter::set_reset_trigger(const std::shared_ptr<Node>& trigger) { m_reset_trigger = trigger; }
26void Counter::reset() { m_count = 0; }
27
28void Counter::on_increment(const TypedHook<GeneratorContext>& callback) { m_increment_callbacks.push_back(callback); }
29void Counter::on_wrap(const TypedHook<GeneratorContext>& callback) { m_wrap_callbacks.push_back(callback); }
30void Counter::on_count(uint32_t target, const TypedHook<GeneratorContext>& callback) { m_count_callbacks.emplace_back(target, callback); }
31
32bool Counter::remove_hook(const NodeHook& callback)
33{
34 bool r = safe_remove_callback(m_callbacks, callback);
35 auto erase_typed = [&](auto& vec) {
36 auto before = vec.size();
37 std::erase_if(vec, [&](const auto& cb) {
38 return cb.target_type() == callback.target_type();
39 });
40 return vec.size() < before;
41 };
42 r |= erase_typed(m_increment_callbacks);
43 r |= erase_typed(m_wrap_callbacks);
44 std::erase_if(m_count_callbacks, [&](const auto& p) {
45 return p.second.target_type() == callback.target_type();
46 });
47 return r;
48}
49
51{
52 m_callbacks.clear();
55 m_wrap_callbacks.clear();
56 m_count_callbacks.clear();
57}
58
59double Counter::process_sample(double /*input*/)
60{
61 if (m_reset_trigger) {
62 atomic_inc_modulator_count(m_reset_trigger->m_modulator_count, 1);
63 uint32_t state = m_reset_trigger->m_state.load();
64
65 double trigger_val = 0.0;
66 if (state & NodeState::PROCESSED) {
67 trigger_val = m_reset_trigger->get_last_output();
68 } else {
69 trigger_val = m_reset_trigger->process_sample(0.0);
71 }
72
73 if (trigger_val != 0.0 && m_last_trigger_value == 0.0) {
74 m_count = 0;
75 }
76 m_last_trigger_value = trigger_val;
77 }
78
79 m_wrapped = false;
80 if (m_modulo > 0) {
81 auto prev = static_cast<int32_t>(m_count);
82 int32_t next = (prev + m_step);
83 int32_t wrapped = ((next % static_cast<int32_t>(m_modulo)) + static_cast<int32_t>(m_modulo)) % static_cast<int32_t>(m_modulo);
84 m_wrapped = (wrapped < prev && m_step > 0) || (wrapped > prev && m_step < 0);
85 m_count = static_cast<uint32_t>(wrapped);
86 } else {
87 m_count += static_cast<uint32_t>(m_step);
88 }
89
90 double output = (m_modulo > 1)
91 ? static_cast<double>(m_count) / static_cast<double>(m_modulo - 1)
92 : static_cast<double>(m_count);
93
94 output *= m_amplitude;
95 m_last_output = output;
96
98 && !m_networked_node) {
99 notify_tick(output);
100 }
101
102 if (m_reset_trigger) {
103 atomic_dec_modulator_count(m_reset_trigger->m_modulator_count, 1);
105 }
106
107 return output;
108}
109
110std::vector<double> Counter::process_batch(unsigned int num_samples)
111{
112 std::vector<double> out(num_samples);
113 for (unsigned int i = 0; i < num_samples; ++i) {
114 out[i] = process_sample(0.0);
115 }
116 return out;
117}
118
119void Counter::notify_tick(double value)
120{
121 update_context(value);
122 auto& ctx = get_last_context();
123 auto& gc = dynamic_cast<GeneratorContext&>(ctx);
124
125 for (auto& cb : m_callbacks) {
126 cb(ctx);
127 }
128 for (auto& [cb, cond] : m_conditional_callbacks) {
129 if (cond(ctx)) {
130 cb(ctx);
131 }
132 }
133 for (auto& cb : m_increment_callbacks) {
134 cb(gc);
135 }
136 if (m_wrapped) {
137 for (auto& cb : m_wrap_callbacks) {
138 cb(gc);
139 }
140 }
141 for (auto& [target, cb] : m_count_callbacks) {
142 if (m_count == target) {
143 cb(gc);
144 }
145 }
146}
147
148void Counter::update_context(double value)
149{
150 m_context = GeneratorContext(value, 0.F, m_amplitude, static_cast<double>(m_count));
151}
152
157
170
183
184} // namespace MayaFlux::Nodes::Generatorx::Nodes::Generator
std::vector< TypedHook< GeneratorContext > > m_increment_callbacks
Definition Counter.hpp:136
bool remove_hook(const NodeHook &callback) override
Removes a previously registered callback.
Definition Counter.cpp:32
void save_state() override
Saves the node's current state for later restoration Recursively cascades through all connected modul...
Definition Counter.cpp:158
void on_count(uint32_t target, const TypedHook< GeneratorContext > &callback)
Registers a callback fired when the counter reaches a specific raw value.
Definition Counter.cpp:30
void reset()
Resets counter to zero immediately.
Definition Counter.cpp:26
std::vector< double > process_batch(unsigned int num_samples) override
Processes multiple samples at once.
Definition Counter.cpp:110
void set_reset_trigger(const std::shared_ptr< Node > &trigger)
Connects a reset trigger node.
Definition Counter.cpp:24
std::vector< TypedHook< GeneratorContext > > m_wrap_callbacks
Definition Counter.hpp:137
void restore_state() override
Restores the node's state from the last save Recursively cascades through all connected modulator nod...
Definition Counter.cpp:171
void update_context(double value) override
Updates the context object for callbacks.
Definition Counter.cpp:148
void on_wrap(const TypedHook< GeneratorContext > &callback)
Registers a callback fired when the counter wraps to zero.
Definition Counter.cpp:29
void set_step(int32_t step)
Sets the step increment.
Definition Counter.cpp:23
void remove_all_hooks() override
Removes all registered callbacks.
Definition Counter.cpp:50
void notify_tick(double value) override
Notifies all registered callbacks with the current context.
Definition Counter.cpp:119
Counter(uint32_t modulo=16, int32_t step=1)
Construct with modulo and step.
Definition Counter.cpp:5
std::vector< std::pair< uint32_t, TypedHook< GeneratorContext > > > m_count_callbacks
Definition Counter.hpp:138
void on_increment(const TypedHook< GeneratorContext > &callback)
Registers a callback fired on every increment.
Definition Counter.cpp:28
std::shared_ptr< Node > m_reset_trigger
Definition Counter.hpp:127
void set_modulo(uint32_t modulo)
Sets the wrap boundary.
Definition Counter.cpp:22
void clear_reset_trigger()
Disconnects the reset trigger node.
Definition Counter.cpp:25
NodeContext & get_last_context() override
Retrieves the last created context object.
Definition Counter.cpp:153
double process_sample(double input=0.0) override
Processes a single data sample.
Definition Counter.cpp:59
Specialized context for generator node callbacks.
Definition Generator.hpp:24
float m_frequency
Base frequency of the generator.
double m_amplitude
Base amplitude of the generator.
Base context class for node callbacks.
Definition Node.hpp:30
std::vector< NodeHook > m_callbacks
Collection of standard callback functions.
Definition Node.hpp:426
bool m_state_saved
tracks if the node's state has been saved by a snapshot operation
Definition Node.hpp:449
bool m_networked_node
Flag indicating if the node is part of a NodeNetwork This flag is used to disable event firing when t...
Definition Node.hpp:444
double m_last_output
The most recent sample value generated by this oscillator.
Definition Node.hpp:397
bool m_fire_events_during_snapshot
Internal flag controlling whether notify_tick fires during state snapshots Default: false (events don...
Definition Node.hpp:479
std::vector< std::pair< NodeHook, NodeCondition > > m_conditional_callbacks
Collection of conditional callback functions with their predicates.
Definition Node.hpp:436
TypedHook<> NodeHook
Alias for TypedHook<NodeContext>.
Definition NodeUtils.hpp:38
@ PROCESSED
Node has been processed this cycle.
Definition NodeSpec.hpp:49
void atomic_add_flag(std::atomic< NodeState > &state, NodeState flag)
Atomically adds a flag to a node state.
Definition NodeUtils.cpp:60
void try_reset_processed_state(std::shared_ptr< Node > node)
Attempts to reset the processed state of a node.
Definition NodeUtils.cpp:97
void atomic_inc_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically increments the modulator count by a specified amount.
Definition NodeUtils.cpp:87
std::function< void(ContextT &)> TypedHook
Callback function type for node processing events, parameterised on context type.
Definition NodeUtils.hpp:28
bool safe_remove_callback(std::vector< TypedHook< ContextT > > &callbacks, const TypedHook< ContextT > &callback)
Removes all callbacks whose target_type() matches that of the supplied callback.
Definition NodeUtils.hpp:92
void atomic_dec_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically decrements the modulator count by a specified amount.
Definition NodeUtils.cpp:92