MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Phasor.cpp
Go to the documentation of this file.
1#include "Phasor.hpp"
2
4
5Phasor::Phasor(float frequency, double amplitude, float offset)
6 : m_offset(offset)
7 , m_frequency_modulator(nullptr)
8 , m_amplitude_modulator(nullptr)
9 , m_phase_wrapped(false)
10 , m_threshold_crossed(false)
11{
12 m_amplitude = amplitude;
15}
16
17Phasor::Phasor(const std::shared_ptr<Node>& frequency_modulator, float frequency, double amplitude, float offset)
18 : m_offset(offset)
19 , m_frequency_modulator(frequency_modulator)
20 , m_amplitude_modulator(nullptr)
21 , m_phase_wrapped(false)
22 , m_threshold_crossed(false)
23{
24 m_amplitude = amplitude;
27}
28
29Phasor::Phasor(float frequency, const std::shared_ptr<Node>& amplitude_modulator, double amplitude, float offset)
30 : m_offset(offset)
31 , m_frequency_modulator(nullptr)
32 , m_amplitude_modulator(amplitude_modulator)
33 , m_phase_wrapped(false)
34 , m_threshold_crossed(false)
35{
36 m_amplitude = amplitude;
38}
39
40Phasor::Phasor(const std::shared_ptr<Node>& frequency_modulator, const std::shared_ptr<Node>& amplitude_modulator,
41 float frequency, double amplitude, float offset)
42 : m_offset(offset)
43 , m_frequency_modulator(frequency_modulator)
44 , m_amplitude_modulator(amplitude_modulator)
45 , m_phase_wrapped(false)
46 , m_threshold_crossed(false)
47{
48 m_amplitude = amplitude;
51}
52
58
63
64void Phasor::set_frequency_modulator(const std::shared_ptr<Node>& modulator)
65{
66 m_frequency_modulator = modulator;
67}
68
69void Phasor::set_amplitude_modulator(const std::shared_ptr<Node>& modulator)
70{
71 m_amplitude_modulator = modulator;
72}
73
75{
76 m_frequency_modulator = nullptr;
77 m_amplitude_modulator = nullptr;
78}
79
81{
82 double output = 0.0;
83
84 double effective_freq = m_frequency;
85
88 uint32_t state = m_frequency_modulator->m_state.load();
89 if (state & NodeState::PROCESSED) {
90 effective_freq += m_frequency_modulator->get_last_output();
91 } else {
92 effective_freq = m_frequency_modulator->process_sample(0.F);
94 }
95
96 update_phase_increment(effective_freq);
97 }
98
99 output = m_phase * m_amplitude;
100
103 uint32_t state = m_amplitude_modulator->m_state.load();
104 if (state & NodeState::PROCESSED) {
105 output *= m_amplitude_modulator->get_last_output();
106 } else {
107 output *= m_amplitude_modulator->process_sample(0.F);
109 }
110 }
111
112 output += m_offset;
113
115 if (m_phase >= 1.0) {
116 m_phase -= 1.0;
117 m_phase_wrapped = true;
118 }
119
120 m_last_output = output;
121
123 && !m_networked_node) {
124 notify_tick(output);
125 }
126
130 }
134 }
135
136 return output;
137}
138
139std::vector<double> Phasor::process_batch(unsigned int num_samples)
140{
141 std::vector<double> output(num_samples, 0.0);
142
143 for (unsigned int i = 0; i < num_samples; ++i) {
144 output[i] = process_sample(0.0); // Use 0.0 as default input
145 }
146
147 return output;
148}
149
150void Phasor::reset(float frequency, float amplitude, float offset, double phase)
151{
153 m_amplitude = amplitude;
154 m_offset = offset;
155 m_phase = phase;
156
157 while (m_phase >= 1.0)
158 m_phase -= 1.0;
159 while (m_phase < 0.0)
160 m_phase += 1.0;
161
163 m_last_output = 0.0;
164}
165
170
171void Phasor::on_threshold(const TypedHook<GeneratorContext>& callback, double threshold, bool /*rising*/)
172{
173 std::pair<TypedHook<GeneratorContext>, double> entry = std::make_pair(callback, threshold);
174 for (auto& pair : m_threshold_callbacks) {
175 if (pair.first.target_type() == callback.target_type() && pair.second == threshold) {
176 return;
177 }
178 }
179 m_threshold_callbacks.push_back(entry);
180}
181
183{
184 for (auto it = m_threshold_callbacks.begin(); it != m_threshold_callbacks.end(); ++it) {
185 if (it->first.target_type() == callback.target_type()) {
186 m_threshold_callbacks.erase(it);
187 return true;
188 }
189 }
190 return false;
191}
192
194{
195 return remove_threshold_callback(callback);
196}
197
198void Phasor::notify_tick(double value)
199{
200 update_context(value);
201
202 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
203 auto& ctx = static_cast<GeneratorContext&>(get_last_context());
204
205 for (auto& callback : m_callbacks) {
206 callback(ctx);
207 }
208
209 if (m_phase_wrapped) {
210 for (auto& callback : m_phase_wrap_callbacks) {
211 callback(ctx);
212 }
213 }
214
215 for (auto& [callback, condition] : m_conditional_callbacks) {
216 if (condition(ctx)) {
217 callback(ctx);
218 }
219 }
220
221 for (auto& [callback, threshold] : m_threshold_callbacks) {
222 if (value >= threshold && !m_threshold_crossed) {
223 callback(ctx);
224 m_threshold_crossed = true;
225 } else if (value < threshold) {
226 m_threshold_crossed = false;
227 }
228 }
229}
230
246
262
263std::vector<std::pair<ModulatorRole, std::shared_ptr<Node>>>
265{
266 std::vector<std::pair<ModulatorRole, std::shared_ptr<Node>>> result;
271 return result;
272}
273
274} // namespace MayaFlux::Nodes::Generator
Core::GlobalInputConfig input
Definition Config.cpp:36
double frequency
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:51
double m_amplitude
Base amplitude of the generator.
virtual void update_context(double value) override
Updates the context object for callbacks.
Definition Generator.cpp:21
double m_phase
Current phase of the generator.
std::shared_ptr< Node > m_frequency_modulator
Node that modulates the frequency.
Definition Phasor.hpp:294
void set_amplitude_modulator(const std::shared_ptr< Node > &modulator)
Sets a node to modulate the generator's amplitude.
Definition Phasor.cpp:69
bool m_threshold_crossed
Flag indicating whether the threshold has been crossed in the current sample.
Definition Phasor.hpp:328
void restore_state() override
Restores the node's state from the last save Recursively cascades through all connected modulator nod...
Definition Phasor.cpp:247
bool m_phase_wrapped
Flag indicating whether the phase has wrapped in the current sample.
Definition Phasor.hpp:323
void set_frequency(float frequency) override
Sets the generator's frequency.
Definition Phasor.cpp:53
bool remove_hook(const TypedHook< GeneratorContext > &callback)
Removes a previously registered callback.
Definition Phasor.cpp:193
std::vector< std::pair< ModulatorRole, std::shared_ptr< Node > > > get_modulators() const override
Retrieves the current modulators connected to this node.
Definition Phasor.cpp:264
std::shared_ptr< Node > m_amplitude_modulator
Node that modulates the amplitude.
Definition Phasor.hpp:299
std::vector< std::pair< TypedHook< GeneratorContext >, double > > m_threshold_callbacks
Collection of threshold-specific callback functions with their thresholds.
Definition Phasor.hpp:318
std::vector< double > process_batch(unsigned int num_samples) override
Processes multiple samples at once.
Definition Phasor.cpp:139
void update_phase_increment(double frequency)
Updates the phase increment based on a new frequency.
Definition Phasor.cpp:59
double m_phase_inc
Phase increment per sample.
Definition Phasor.hpp:284
void on_threshold(const TypedHook< GeneratorContext > &callback, double threshold, bool rising=true)
Registers a callback for every time the phasor crosses a threshold.
Definition Phasor.cpp:171
void notify_tick(double value) override
Notifies all registered callbacks about a new sample.
Definition Phasor.cpp:198
void reset(float frequency=1, float amplitude=1.0, float offset=0, double phase=0.0)
Resets the generator's phase and parameters.
Definition Phasor.cpp:150
void on_phase_wrap(const TypedHook< GeneratorContext > &callback)
Registers a callback for every phase wrap.
Definition Phasor.cpp:166
void set_frequency_modulator(const std::shared_ptr< Node > &modulator)
Sets a node to modulate the generator's frequency.
Definition Phasor.cpp:64
void save_state() override
Saves the node's current state for later restoration Recursively cascades through all connected modul...
Definition Phasor.cpp:231
Phasor(float frequency=1, double amplitude=1, float offset=0)
Basic constructor with fixed parameters.
Definition Phasor.cpp:5
std::vector< TypedHook< GeneratorContext > > m_phase_wrap_callbacks
Collection of phase wrap-specific callback functions.
Definition Phasor.hpp:313
double process_sample(double input=0.) override
Processes a single input sample and generates a phasor sample.
Definition Phasor.cpp:80
bool remove_threshold_callback(const TypedHook< GeneratorContext > &callback)
Removes a previously registered phase wrap callback.
Definition Phasor.cpp:182
void clear_modulators()
Removes all modulation connections.
Definition Phasor.cpp:74
float m_offset
DC offset added to the output.
Definition Phasor.hpp:289
std::vector< NodeHook > m_callbacks
Collection of standard callback functions.
Definition Node.hpp:434
bool m_state_saved
tracks if the node's state has been saved by a snapshot operation
Definition Node.hpp:457
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:452
double m_last_output
The most recent sample value generated by this oscillator.
Definition Node.hpp:405
bool m_fire_events_during_snapshot
Internal flag controlling whether notify_tick fires during state snapshots Default: false (events don...
Definition Node.hpp:487
std::vector< std::pair< NodeHook, NodeCondition > > m_conditional_callbacks
Collection of conditional callback functions with their predicates.
Definition Node.hpp:444
uint32_t m_timing_rate
Current timing rate for the node, used for timing calculations (can be sample rate or frame rate)
Definition Node.hpp:463
@ 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
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
bool safe_add_callback(std::vector< TypedHook< ContextT > > &callbacks, const TypedHook< ContextT > &callback)
Adds a callback to the collection if an equivalent one is not already present.
Definition NodeUtils.hpp:77