MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Impulse.cpp
Go to the documentation of this file.
1#include "Impulse.hpp"
3
5
6Impulse::Impulse(float frequency, double amplitude, float offset)
7 : m_offset(offset)
8 , m_frequency_modulator(nullptr)
9 , m_amplitude_modulator(nullptr)
10 , m_impulse_occurred(false)
11{
12 m_amplitude = amplitude;
13 m_frequency = frequency;
14 update_phase_increment(frequency);
15}
16
17Impulse::Impulse(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_impulse_occurred(false)
22{
23 m_amplitude = amplitude;
24 m_frequency = frequency;
25 update_phase_increment(frequency);
26}
27
28Impulse::Impulse(float frequency, const std::shared_ptr<Node>& amplitude_modulator, double amplitude, float offset)
29 : m_offset(offset)
30 , m_frequency_modulator(nullptr)
31 , m_amplitude_modulator(amplitude_modulator)
32 , m_impulse_occurred(false)
33{
34 m_amplitude = amplitude;
35 m_frequency = frequency;
36 update_phase_increment(frequency);
37}
38
39Impulse::Impulse(const std::shared_ptr<Node>& frequency_modulator, const std::shared_ptr<Node>& amplitude_modulator,
40 float frequency, double amplitude, float offset)
41 : m_offset(offset)
42 , m_frequency_modulator(frequency_modulator)
43 , m_amplitude_modulator(amplitude_modulator)
44 , m_impulse_occurred(false)
45{
46 m_amplitude = amplitude;
47 m_frequency = frequency;
48 update_phase_increment(frequency);
49}
50
51void Impulse::set_frequency(float frequency)
52{
53 m_frequency = frequency;
54 update_phase_increment(frequency);
55}
56
57void Impulse::update_phase_increment(double frequency)
58{
59 uint64_t s_rate = 48000U;
61 s_rate = Config::get_sample_rate();
62 }
63 m_phase_inc = frequency / (double)s_rate;
64}
65
66void Impulse::set_frequency_modulator(const std::shared_ptr<Node>& modulator)
67{
68 m_frequency_modulator = modulator;
69}
70
71void Impulse::set_amplitude_modulator(const std::shared_ptr<Node>& modulator)
72{
73 m_amplitude_modulator = modulator;
74}
75
81
82double Impulse::process_sample(double input)
83{
84 double output = 0.0;
85 m_impulse_occurred = false;
86
87 double effective_freq = m_frequency;
90 uint32_t state = m_frequency_modulator->m_state.load();
91 if (state & Utils::NodeState::PROCESSED) {
92 effective_freq += m_frequency_modulator->get_last_output();
93 } else {
94 effective_freq = m_frequency_modulator->process_sample(0.F);
96 }
97
98 if (effective_freq <= 0) {
99 effective_freq = 0.001;
100 }
101 update_phase_increment(effective_freq);
102 }
103
104 if (m_phase < m_phase_inc) {
105 output = m_amplitude;
106 m_impulse_occurred = true;
107 } else {
108 output = 0.0;
109 }
110
111 double current_amplitude = m_amplitude;
114 uint32_t state = m_amplitude_modulator->m_state.load();
115
116 if (state & Utils::NodeState::PROCESSED) {
117 current_amplitude += m_amplitude_modulator->get_last_output();
118 } else {
119 current_amplitude += m_amplitude_modulator->process_sample(0.F);
121 }
122 }
123
124 output *= current_amplitude;
125 m_amplitude = current_amplitude;
126 output += m_offset;
127
129 if (m_phase >= 1.0) {
130 m_phase -= 1.0;
131 }
132
133 m_last_output = output;
134
136 notify_tick(output);
137
141 }
145 }
146
147 return output;
148}
149
150std::vector<double> Impulse::process_batch(unsigned int num_samples)
151{
152 std::vector<double> output(num_samples, 0.0);
153
154 for (unsigned int i = 0; i < num_samples; ++i) {
155 output[i] = process_sample(0.0); // Use 0.0 as default input
156 }
157
158 return output;
159}
160
161void Impulse::reset(float frequency, float amplitude, float offset)
162{
163 m_phase = 0.0;
164 m_amplitude = amplitude;
165 m_offset = offset;
166 set_frequency(frequency);
167 m_last_output = 0.0;
168}
169
170void Impulse::on_impulse(const NodeHook& callback)
171{
173}
174
175bool Impulse::remove_hook(const NodeHook& callback)
176{
177 bool removed_from_tick = safe_remove_callback(m_callbacks, callback);
178 bool removed_from_impulse = safe_remove_callback(m_impulse_callbacks, callback);
179 return removed_from_tick || removed_from_impulse;
180}
181
182void Impulse::notify_tick(double value)
183{
185
186 for (auto& callback : m_callbacks) {
187 callback(*m_last_context);
188 }
189 for (auto& [callback, condition] : m_conditional_callbacks) {
190 if (condition(*m_last_context)) {
191 callback(*m_last_context);
192 }
193 }
194 if (m_impulse_occurred) {
195 for (auto& callback : m_impulse_callbacks) {
196 callback(*m_last_context);
197 }
198 }
199}
200
216
232
233} // namespace MayaFlux::Nodes::Generator
virtual std::unique_ptr< NodeContext > create_context(double value) override
Creates a context object for callbacks.
Definition Generator.cpp:19
float m_frequency
Base frequency of the generator.
double m_amplitude
Base amplitude of the generator.
double m_phase
Current phase of the generator.
bool remove_hook(const NodeHook &callback) override
Removes a previously registered callback.
Definition Impulse.cpp:175
std::shared_ptr< Node > m_amplitude_modulator
Node that modulates the amplitude.
Definition Impulse.hpp:262
void restore_state() override
Restores the node's state from the last save Recursively cascades through all connected modulator nod...
Definition Impulse.cpp:217
void save_state() override
Saves the node's current state for later restoration Recursively cascades through all connected modul...
Definition Impulse.cpp:201
void notify_tick(double value) override
Notifies all registered callbacks about a new sample.
Definition Impulse.cpp:182
std::vector< NodeHook > m_impulse_callbacks
Collection of impulse-specific callback functions.
Definition Impulse.hpp:276
double m_phase_inc
Phase increment per sample.
Definition Impulse.hpp:247
Impulse(float frequency=1, double amplitude=1, float offset=0)
Basic constructor with fixed parameters.
Definition Impulse.cpp:6
std::vector< double > process_batch(unsigned int num_samples) override
Processes multiple samples at once.
Definition Impulse.cpp:150
double process_sample(double input=0.) override
Processes a single input sample and generates an impulse sample.
Definition Impulse.cpp:82
void reset(float frequency=1, float amplitude=1.0F, float offset=0)
Resets the generator's phase and parameters.
Definition Impulse.cpp:161
void clear_modulators()
Removes all modulation connections.
Definition Impulse.cpp:76
float m_offset
DC offset added to the output.
Definition Impulse.hpp:252
void update_phase_increment(double frequency)
Updates the phase increment based on a new frequency.
Definition Impulse.cpp:57
void set_frequency_modulator(const std::shared_ptr< Node > &modulator)
Sets a node to modulate the generator's frequency.
Definition Impulse.cpp:66
void on_impulse(const NodeHook &callback)
Registers a callback for every impulse.
Definition Impulse.cpp:170
void set_frequency(float frequency) override
Sets the generator's frequency.
Definition Impulse.cpp:51
std::shared_ptr< Node > m_frequency_modulator
Node that modulates the frequency.
Definition Impulse.hpp:257
void set_amplitude_modulator(const std::shared_ptr< Node > &modulator)
Sets a node to modulate the generator's amplitude.
Definition Impulse.cpp:71
std::vector< NodeHook > m_callbacks
Collection of standard callback functions.
Definition Node.hpp:416
double m_last_output
The most recent sample value generated by this oscillator.
Definition Node.hpp:378
bool m_fire_events_during_snapshot
Internal flag controlling whether notify_tick fires during state snapshots Default: false (events don...
Definition Node.hpp:448
std::vector< std::pair< NodeHook, NodeCondition > > m_conditional_callbacks
Collection of conditional callback functions with their predicates.
Definition Node.hpp:426
std::unique_ptr< NodeContext > m_last_context
The last context object created for callbacks.
Definition Node.hpp:396
uint32_t get_sample_rate()
Gets the sample rate from the default engine.
Definition Config.cpp:46
std::function< void(NodeContext &)> NodeHook
Callback function type for node processing events.
Definition NodeUtils.hpp:25
void atomic_add_flag(std::atomic< Utils::NodeState > &state, Utils::NodeState flag)
Atomically adds a flag to a node state.
Definition NodeUtils.cpp:96
bool safe_add_callback(std::vector< NodeHook > &callbacks, const NodeHook &callback)
Safely adds a callback to a collection if it doesn't already exist.
Definition NodeUtils.cpp:33
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.
void atomic_dec_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically decrements the modulator count by a specified amount.
bool safe_remove_callback(std::vector< NodeHook > &callbacks, const NodeHook &callback)
Safely removes a callback from a collection.
Definition NodeUtils.cpp:51
@ PROCESSED
Node has been processed this cycle.
Definition Utils.hpp:34
bool is_engine_initialized()
Checks if the default audio engine is initialized.
Definition Config.cpp:9