MayaFlux 1.0.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;
12}
13
14Counter::Counter(const std::shared_ptr<Node>& reset_trigger, uint32_t modulo, int32_t step)
15 : m_modulo(modulo)
16 , m_step(step)
17 , m_reset_trigger(reset_trigger)
18{
19 m_amplitude = 1.0;
20 m_frequency = 0.F;
22}
23
24void Counter::set_modulo(uint32_t modulo) { m_modulo = modulo; }
25void Counter::set_step(int32_t step) { m_step = step; }
26void Counter::set_reset_trigger(const std::shared_ptr<Node>& trigger) { m_reset_trigger = trigger; }
28void Counter::reset() { m_count = 0; }
29
34
39
41{
42 return m_count_callbacks.add(adapt_hook(callback), callback.target_type(), 0, { static_cast<double>(target), 0.0 });
43}
44
46{
47 const auto& key = callback.target_type();
48 bool removed = m_callbacks.remove_by_key(key);
50 removed |= m_wrap_callbacks.remove_by_key(key);
51 removed |= m_count_callbacks.remove_by_key(key);
52 return removed;
53}
54
55double Counter::process_sample(double /*input*/)
56{
57 if (m_reset_trigger) {
58 atomic_inc_modulator_count(m_reset_trigger->m_modulator_count, 1);
59 uint32_t state = m_reset_trigger->m_state.load();
60
61 double trigger_val = 0.0;
62 if (state & NodeState::PROCESSED) {
63 trigger_val = m_reset_trigger->get_last_output();
64 } else {
65 trigger_val = m_reset_trigger->process_sample(0.0);
67 }
68
69 if (trigger_val != 0.0 && m_last_trigger_value == 0.0) {
70 m_count = 0;
71 }
72 m_last_trigger_value = trigger_val;
73 }
74
75 m_wrapped = false;
76 if (m_modulo > 0) {
77 auto prev = static_cast<int32_t>(m_count);
78 int32_t next = (prev + m_step);
79 int32_t wrapped = ((next % static_cast<int32_t>(m_modulo)) + static_cast<int32_t>(m_modulo)) % static_cast<int32_t>(m_modulo);
80 m_wrapped = (wrapped < prev && m_step > 0) || (wrapped > prev && m_step < 0);
81 m_count = static_cast<uint32_t>(wrapped);
82 } else {
83 m_count += static_cast<uint32_t>(m_step);
84 }
85
86 double output = (m_modulo > 1)
87 ? static_cast<double>(m_count) / static_cast<double>(m_modulo - 1)
88 : static_cast<double>(m_count);
89
90 output *= m_amplitude;
91 m_last_output = output;
92
94 && !m_networked_node) {
95 notify_tick(output);
96 }
97
98 if (m_reset_trigger) {
99 atomic_dec_modulator_count(m_reset_trigger->m_modulator_count, 1);
101 }
102
103 return output;
104}
105
106std::vector<double> Counter::process_batch(unsigned int num_samples)
107{
108 std::vector<double> out(num_samples);
109 for (unsigned int i = 0; i < num_samples; ++i) {
110 out[i] = process_sample(0.0);
111 }
112 return out;
113}
114
116{
118 auto& ctx = get_last_context();
119
120 m_callbacks.fire(ctx);
123 if (m_wrapped) {
125 }
126 for (const auto& entry : m_count_callbacks.snapshot()) {
127 if (m_count == static_cast<uint32_t>(entry.params[0])) {
128 entry.hook(ctx);
129 }
130 }
131}
132
134{
135 m_context = GeneratorContext(value, 0.F, m_amplitude, static_cast<double>(m_count));
136}
137
150
163
164std::vector<std::pair<ModulatorRole, std::shared_ptr<Node>>>
166{
167 if (m_reset_trigger)
169 return {};
170}
171
172} // namespace MayaFlux::Nodes::Generatorx::Nodes::Generator
PickCallback callback
Definition Picker.cpp:22
std::vector< float > * out
glm::vec3 value
HookId on_count(uint32_t target, const TypedHook< GeneratorContext > &callback)
Registers a callback fired when the counter reaches a specific raw value.
Definition Counter.cpp:40
bool remove_hook(const NodeHook &callback) override
Removes a previously registered callback.
Definition Counter.cpp:45
void save_state() override
Saves the node's current state for later restoration Recursively cascades through all connected modul...
Definition Counter.cpp:138
HookId on_wrap(const TypedHook< GeneratorContext > &callback)
Registers a callback fired when the counter wraps to zero.
Definition Counter.cpp:35
void reset()
Resets counter to zero immediately.
Definition Counter.cpp:28
std::vector< double > process_batch(unsigned int num_samples) override
Processes multiple samples at once.
Definition Counter.cpp:106
void set_reset_trigger(const std::shared_ptr< Node > &trigger)
Connects a reset trigger node.
Definition Counter.cpp:26
void restore_state() override
Restores the node's state from the last save Recursively cascades through all connected modulator nod...
Definition Counter.cpp:151
void update_context(double value) override
Updates the context object for callbacks.
Definition Counter.cpp:133
void set_step(int32_t step)
Sets the step increment.
Definition Counter.cpp:25
void notify_tick(double value) override
Notifies all registered callbacks with the current context.
Definition Counter.cpp:115
Counter(uint32_t modulo=16, int32_t step=1)
Construct with modulo and step.
Definition Counter.cpp:5
std::shared_ptr< Node > m_reset_trigger
Definition Counter.hpp:128
std::vector< std::pair< ModulatorRole, std::shared_ptr< Node > > > get_modulators() const override
Retrieves the current modulators connected to this node.
Definition Counter.cpp:165
HookId on_increment(const TypedHook< GeneratorContext > &callback)
Registers a callback fired on every increment.
Definition Counter.cpp:30
void set_modulo(uint32_t modulo)
Sets the wrap boundary.
Definition Counter.cpp:24
void clear_reset_trigger()
Disconnects the reset trigger node.
Definition Counter.cpp:27
double process_sample(double input=0.0) override
Processes a single data sample.
Definition Counter.cpp:55
Specialized context for generator node callbacks.
Definition Generator.hpp:24
float m_frequency
Base frequency of the generator.
NodeContext & get_last_context() override
Gets the last created context object.
Definition Generator.cpp:37
double m_amplitude
Base amplitude of the generator.
HookId add(NodeHook hook, const std::type_info &key, uint8_t tag=0, std::array< double, 2 > params={})
Appends a hook with no duplicate check and returns its id.
Snapshot snapshot() const
The current entries, held stable for the lifetime of the returned object.
Definition NodeUtils.cpp:43
bool remove_by_key(const std::type_info &key)
Removes every entry registered with this callable type.
void fire(NodeContext &ctx) const
Calls every entry whose condition, if any, holds.
Definition NodeUtils.cpp:68
HookList m_conditional_callbacks
Hooks fired on a tick only while their condition holds.
Definition Node.hpp:485
bool m_state_saved
tracks if the node's state has been saved by a snapshot operation
Definition Node.hpp:498
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:493
double m_last_output
The most recent sample value generated by this oscillator.
Definition Node.hpp:441
HookList m_callbacks
Hooks fired on every tick.
Definition Node.hpp:478
bool m_fire_events_during_snapshot
Internal flag controlling whether notify_tick fires during state snapshots Default: false (events don...
Definition Node.hpp:528
TypedHook<> NodeHook
Alias for TypedHook<NodeContext>.
Definition NodeUtils.hpp:38
@ PROCESSED
Node has been processed this cycle.
Definition NodeSpec.hpp:49
void try_reset_processed_state(std::shared_ptr< Node > node)
Attempts to reset the processed state of a node.
void atomic_inc_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically increments the modulator count by a specified amount.
uint64_t HookId
Identifies one registration inside a HookList.
Definition NodeUtils.hpp:60
void atomic_dec_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically decrements the modulator count by a specified amount.
std::function< void(ContextT &)> TypedHook
Callback function type for node processing events, parameterised on context type.
Definition NodeUtils.hpp:28
NodeHook adapt_hook(const TypedHook< ContextT > &hook)
Wraps a context-typed hook into a NodeHook.
void atomic_add_flag(std::atomic< NodeState > &state, NodeState flag)
Atomically adds a flag to a node state.