MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Impulse.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Generator.hpp"
4
6
7/**
8 * @class Impulse
9 * @brief Impulse generator node
10 *
11 * The Impulse class generates a single spike followed by zeros, which is a fundamental
12 * signal used in digital signal processing. It produces a value of 1.0 (or specified amplitude)
13 * at specified intervals, and 0.0 elsewhere.
14 *
15 * Key features:
16 * - Configurable frequency, amplitude, and DC offset
17 * - Support for frequency modulation (changing impulse rate)
18 * - Support for amplitude modulation (changing impulse height)
19 * - Automatic registration with the node graph manager (optional)
20 * - Precise timing control for impulse generation
21 *
22 * Impulse generators are used extensively in audio and signal processing for:
23 * - Triggering events at specific intervals
24 * - Testing system responses (impulse response)
25 * - Creating click trains and metronome-like signals
26 * - Serving as the basis for more complex event-based generators
27 * - Synchronization signals for other generators
28 *
29 * The implementation uses a phase accumulation approach similar to other oscillators
30 * but only outputs a non-zero value at the beginning of each cycle.
31 */
32class MAYAFLUX_API Impulse : public Generator, public std::enable_shared_from_this<Impulse> {
33public:
34 /**
35 * @brief Basic constructor with fixed parameters
36 * @param frequency Impulse repetition rate in Hz (default: 1Hz, one impulse per second)
37 * @param amplitude Impulse amplitude (default: 1.0)
38 * @param offset DC offset added to the output (default: 0.0)
39 *
40 * Creates an impulse generator with fixed frequency and amplitude.
41 */
42 Impulse(float frequency = 1, double amplitude = 1, float offset = 0);
43
44 /**
45 * @brief Constructor with frequency modulation
46 * @param frequency_modulator Node that modulates the frequency
47 * @param frequency Base frequency in Hz (default: 1Hz)
48 * @param amplitude Impulse amplitude (default: 1.0)
49 * @param offset DC offset added to the output (default: 0.0)
50 *
51 * Creates an impulse generator with frequency modulation, where the actual frequency
52 * is the base frequency plus the output of the modulator node.
53 */
54 Impulse(const std::shared_ptr<Node>& frequency_modulator, float frequency = 1, double amplitude = 1, float offset = 0);
55
56 /**
57 * @brief Constructor with amplitude modulation
58 * @param frequency Impulse repetition rate in Hz
59 * @param amplitude_modulator Node that modulates the amplitude
60 * @param amplitude Base amplitude (default: 1.0)
61 * @param offset DC offset added to the output (default: 0.0)
62 *
63 * Creates an impulse generator with amplitude modulation, where the actual amplitude
64 * is the base amplitude multiplied by the output of the modulator node.
65 */
66 Impulse(float frequency, const std::shared_ptr<Node>& amplitude_modulator, double amplitude = 1, float offset = 0);
67
68 /**
69 * @brief Constructor with both frequency and amplitude modulation
70 * @param frequency_modulator Node that modulates the frequency
71 * @param amplitude_modulator Node that modulates the amplitude
72 * @param frequency Base frequency in Hz (default: 1Hz)
73 * @param amplitude Base amplitude (default: 1.0)
74 * @param offset DC offset added to the output (default: 0.0)
75 *
76 * Creates an impulse generator with both frequency and amplitude modulation,
77 * enabling complex timing and amplitude control.
78 */
79 Impulse(const std::shared_ptr<Node>& frequency_modulator, const std::shared_ptr<Node>& amplitude_modulator,
80 float frequency = 1, double amplitude = 1, float offset = 0);
81
82 /**
83 * @brief Virtual destructor
84 */
85 ~Impulse() override = default;
86
87 /**
88 * @brief Processes a single input sample and generates an impulse sample
89 * @param input Input sample (used for modulation when modulators are connected)
90 * @return Generated impulse sample (1.0 at the start of each cycle, 0.0 elsewhere)
91 *
92 * This method advances the generator's phase and computes the next
93 * sample of the impulse train, applying any modulation from connected nodes.
94 */
95 double process_sample(double input = 0.) override;
96
97 /**
98 * @brief Processes multiple samples at once
99 * @param num_samples Number of samples to generate
100 * @return Vector of generated impulse samples
101 *
102 * This method is more efficient than calling process_sample() repeatedly
103 * when generating multiple samples at once.
104 */
105 std::vector<double> process_batch(unsigned int num_samples) override;
106
107 /**
108 * @brief Prints a visual representation of the impulse train
109 *
110 * Outputs a text-based graph of the impulse pattern over time,
111 * useful for debugging and visualization.
112 */
113 inline void printGraph() override { }
114
115 /**
116 * @brief Prints the current parameters of the impulse generator
117 *
118 * Outputs the current frequency, amplitude, offset, and modulation
119 * settings of the generator.
120 */
121 inline void printCurrent() override { }
122
123 /**
124 * @brief Sets the generator's frequency
125 * @param frequency New frequency in Hz
126 *
127 * Updates the generator's frequency, which controls how often impulses occur.
128 */
129 void set_frequency(float frequency) override;
130
131 /**
132 * @brief Gets the current base frequency
133 * @return Current frequency in Hz
134 */
135 inline float get_frequency() const { return m_frequency; }
136
137 /**
138 * @brief Sets all basic parameters at once
139 * @param frequency New frequency in Hz
140 * @param amplitude New amplitude
141 * @param offset New DC offset
142 *
143 * This is more efficient than setting parameters individually
144 * when multiple parameters need to be changed.
145 */
146 inline void set_params(float frequency, double amplitude, float offset)
147 {
148 m_amplitude = amplitude;
149 m_offset = offset;
150 set_frequency(frequency);
151 }
152
153 /**
154 * @brief Sets a node to modulate the generator's frequency
155 * @param modulator Node that will modulate the frequency
156 *
157 * The modulator's output is added to the base frequency,
158 * enabling dynamic control of impulse timing.
159 */
160 void set_frequency_modulator(const std::shared_ptr<Node>& modulator);
161
162 /**
163 * @brief Sets a node to modulate the generator's amplitude
164 * @param modulator Node that will modulate the amplitude
165 *
166 * The modulator's output is multiplied with the base amplitude,
167 * enabling dynamic control of impulse height.
168 */
169 void set_amplitude_modulator(const std::shared_ptr<Node>& modulator);
170
171 /**
172 * @brief Removes all modulation connections
173 *
174 * After calling this method, the generator will use only its
175 * base frequency and amplitude without any modulation.
176 */
177 void clear_modulators();
178
179 /**
180 * @brief Resets the generator's phase and parameters
181 * @param frequency New frequency in Hz (default: 1Hz)
182 * @param amplitude New amplitude (default: 1.0)
183 * @param offset New DC offset (default: 0)
184 *
185 * This method resets the generator's internal state and parameters,
186 * effectively restarting it from the beginning of its cycle.
187 */
188 void reset(float frequency = 1, float amplitude = 1.0F, float offset = 0);
189
190 /**
191 * @brief Registers a callback for every impulse
192 * @param callback Function to call when an impulse occurs
193 *
194 * This method allows external components to monitor or react to
195 * every impulse produced by the generator. The callback
196 * receives a GeneratorContext containing the generated value and
197 * generator parameters like frequency, amplitude, and phase.
198 */
199 void on_impulse(const NodeHook& callback);
200
201 /**
202 * @brief Removes a previously registered callback
203 * @param callback The callback function to remove
204 * @return True if the callback was found and removed, false otherwise
205 *
206 * Unregisters a callback previously added with on_tick(), stopping
207 * it from receiving further notifications about generated samples.
208 */
209 bool remove_hook(const NodeHook& callback) override;
210
211 /**
212 * @brief Removes all registered callbacks
213 *
214 * Clears all standard and conditional callbacks, effectively
215 * disconnecting all external components from this generator's
216 * notification system. Useful when reconfiguring the processing
217 * graph or shutting down components.
218 */
219 inline void remove_all_hooks() override
220 {
221 m_callbacks.clear();
222 m_conditional_callbacks.clear();
223 m_impulse_callbacks.clear();
224 }
225
226 void save_state() override;
227 void restore_state() override;
228
229protected:
230 /**
231 * @brief Notifies all registered callbacks about a new sample
232 * @param value The newly generated sample
233 *
234 * This method is called internally whenever a new sample is generated,
235 * creating the appropriate context and invoking all registered callbacks
236 * that should receive notification about this sample.
237 */
238 void notify_tick(double value) override;
239
240private:
241 /**
242 * @brief Phase increment per sample
243 *
244 * This value determines how much the phase advances with each sample,
245 * controlling the generator's frequency.
246 */
247 double m_phase_inc {};
248
249 /**
250 * @brief DC offset added to the output
251 */
252 float m_offset;
253
254 /**
255 * @brief Node that modulates the frequency
256 */
257 std::shared_ptr<Node> m_frequency_modulator;
258
259 /**
260 * @brief Node that modulates the amplitude
261 */
262 std::shared_ptr<Node> m_amplitude_modulator;
263
264 /**
265 * @brief Updates the phase increment based on a new frequency
266 * @param frequency New frequency in Hz
267 *
268 * This method calculates the phase increment needed to produce
269 * impulses at the specified frequency at the current sample rate.
270 */
271 void update_phase_increment(double frequency);
272
273 /**
274 * @brief Collection of impulse-specific callback functions
275 */
276 std::vector<NodeHook> m_impulse_callbacks;
277
279
280 double m_saved_phase {};
281 float m_saved_frequency {};
282 float m_saved_offset {};
283 double m_saved_phase_inc {};
284 double m_saved_last_output {};
285
286 bool m_state_saved {};
287};
288}
Base class for all signal and pattern generators in Maya Flux.
std::shared_ptr< Node > m_amplitude_modulator
Node that modulates the amplitude.
Definition Impulse.hpp:262
void printCurrent() override
Prints the current parameters of the impulse generator.
Definition Impulse.hpp:121
~Impulse() override=default
Virtual destructor.
void set_params(float frequency, double amplitude, float offset)
Sets all basic parameters at once.
Definition Impulse.hpp:146
std::vector< NodeHook > m_impulse_callbacks
Collection of impulse-specific callback functions.
Definition Impulse.hpp:276
float get_frequency() const
Gets the current base frequency.
Definition Impulse.hpp:135
float m_offset
DC offset added to the output.
Definition Impulse.hpp:252
void remove_all_hooks() override
Removes all registered callbacks.
Definition Impulse.hpp:219
void printGraph() override
Prints a visual representation of the impulse train.
Definition Impulse.hpp:113
std::shared_ptr< Node > m_frequency_modulator
Node that modulates the frequency.
Definition Impulse.hpp:257
Impulse generator node.
Definition Impulse.hpp:32
std::function< void(NodeContext &)> NodeHook
Callback function type for node processing events.
Definition NodeUtils.hpp:25