MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Sine.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Generator.hpp"
4
6
7/**
8 * @class Sine
9 * @brief Sinusoidal oscillator generator node
10 *
11 * The Sine class generates a sinusoidal waveform, which is the fundamental
12 * building block of audio synthesis. Despite its name, this class implements
13 * a general sinusoidal oscillator that can be extended to produce various
14 * waveforms beyond just the mathematical sine function.
15 *
16 * Key features:
17 * - Configurable frequency, amplitude, and DC offset
18 * - Support for frequency modulation (FM synthesis)
19 * - Support for amplitude modulation (AM synthesis)
20 * - Phase continuity to prevent clicks when changing parameters
21 *
22 * Sinusoidal oscillators are used extensively in audio synthesis for:
23 * - Creating pure tones
24 * - Serving as carriers or modulators in FM/AM synthesis
25 * - Building more complex waveforms through additive synthesis
26 * - LFOs (Low Frequency Oscillators) for parameter modulation
27 *
28 * The implementation uses a phase accumulation approach for sample-accurate
29 * frequency control and efficient computation, avoiding repeated calls to
30 * the computationally expensive sin() function.
31 */
32class MAYAFLUX_API Sine : public Generator {
33public:
34 /**
35 * @brief Basic constructor with fixed parameters
36 * @param frequency Oscillation frequency in Hz (default: 440Hz, A4 note)
37 * @param amplitude Output amplitude (default: 1.0)
38 * @param offset DC offset added to the output (default: 0.0)
39 *
40 * Creates a sine oscillator with fixed frequency and amplitude.
41 */
42 Sine(float frequency = 440, 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: 440Hz)
48 * @param amplitude Output amplitude (default: 1.0)
49 * @param offset DC offset added to the output (default: 0.0)
50 *
51 * Creates a sine oscillator with frequency modulation, where the actual frequency
52 * is the base frequency plus the output of the modulator node.
53 */
54 Sine(const std::shared_ptr<Node>& frequency_modulator, float frequency = 440, double amplitude = 1, float offset = 0);
55
56 /**
57 * @brief Constructor with amplitude modulation
58 * @param frequency Oscillation frequency 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 a sine oscillator with amplitude modulation, where the actual amplitude
64 * is the base amplitude multiplied by the output of the modulator node.
65 */
66 Sine(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: 440Hz)
73 * @param amplitude Base amplitude (default: 1.0)
74 * @param offset DC offset added to the output (default: 0.0)
75 *
76 * Creates a sine oscillator with both frequency and amplitude modulation,
77 * enabling complex synthesis techniques like FM and AM simultaneously.
78 */
79 Sine(const std::shared_ptr<Node>& frequency_modulator, const std::shared_ptr<Node>& amplitude_modulator,
80 float frequency = 440, double amplitude = 1, float offset = 0);
81
82 /**
83 * @brief Virtual destructor
84 */
85 ~Sine() override = default;
86
87 /**
88 * @brief Processes a single input sample and generates a sine wave sample
89 * @param input Input sample (used for modulation when modulators are connected)
90 * @return Generated sine wave sample
91 *
92 * This method advances the oscillator's phase and computes the next
93 * sample of the sine wave, 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 sine wave 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 sine wave
109 *
110 * Outputs a text-based graph of the sine wave's shape over time,
111 * useful for debugging and visualization.
112 */
113 void printGraph() override;
114
115 /**
116 * @brief Prints the current parameters of the sine oscillator
117 *
118 * Outputs the current frequency, amplitude, offset, and modulation
119 * settings of the oscillator.
120 */
121 void printCurrent() override;
122
123 /**
124 * @brief Sets the oscillator's frequency
125 * @param frequency New frequency in Hz
126 *
127 * Updates the oscillator's frequency while maintaining phase continuity
128 * to prevent clicks or pops in the audio output.
129 */
130 void set_frequency(float frequency) override;
131
132 /**
133 * @brief Gets the current base frequency
134 * @return Current frequency in Hz
135 */
136 [[nodiscard]] inline float get_frequency() const { return m_frequency; }
137
138 /**
139 * @brief Sets all basic parameters at once
140 * @param frequency New frequency in Hz
141 * @param amplitude New amplitude
142 * @param offset New DC offset
143 *
144 * This is more efficient than setting parameters individually
145 * when multiple parameters need to be changed.
146 */
147 inline void set_params(float frequency, double amplitude, float offset)
148 {
149 m_amplitude = amplitude;
150 m_offset = offset;
151 set_frequency(frequency);
152 }
153
154 /**
155 * @brief Sets a node to modulate the oscillator's frequency
156 * @param modulator Node that will modulate the frequency
157 *
158 * The modulator's output is added to the base frequency,
159 * enabling FM synthesis techniques.
160 */
161 void set_frequency_modulator(const std::shared_ptr<Node>& modulator);
162
163 /**
164 * @brief Sets a node to modulate the oscillator's amplitude
165 * @param modulator Node that will modulate the amplitude
166 *
167 * The modulator's output is multiplied with the base amplitude,
168 * enabling AM synthesis techniques.
169 */
170 void set_amplitude_modulator(const std::shared_ptr<Node>& modulator);
171
172 /**
173 * @brief Removes all modulation connections
174 *
175 * After calling this method, the oscillator will use only its
176 * base frequency and amplitude without any modulation.
177 */
178 void clear_modulators();
179
180 /**
181 * @brief Resets the oscillator's phase and parameters
182 * @param frequency New frequency in Hz (default: 440Hz)
183 * @param amplitude New amplitude (default: 0.5)
184 * @param offset New DC offset (default: 0)
185 *
186 * This method resets the oscillator's internal state and parameters,
187 * effectively restarting it from the beginning of its cycle.
188 */
189 void reset(float frequency = 440, double amplitude = 0.5, float offset = 0);
190
191 void save_state() override;
192 void restore_state() override;
193
194protected:
195 /**
196 * @brief Notifies all registered callbacks about a new sample
197 * @param value The newly generated sample
198 *
199 * This method is called internally whenever a new sample is generated,
200 * creating the appropriate context and invoking all registered callbacks
201 * that should receive notification about this sample.
202 */
203 void notify_tick(double value) override;
204
205private:
206 /**
207 * @brief Phase increment per sample
208 *
209 * This value determines how much the phase advances with each sample,
210 * controlling the oscillator's frequency.
211 */
212 double m_phase_inc {};
213
214 /**
215 * @brief DC offset added to the output
216 */
217 float m_offset {};
218
219 /**
220 * @brief Node that modulates the frequency
221 */
222 std::shared_ptr<Node> m_frequency_modulator;
223
224 /**
225 * @brief Node that modulates the amplitude
226 */
227 std::shared_ptr<Node> m_amplitude_modulator;
228
229 /**
230 * @brief Updates the phase increment based on a new frequency
231 * @param frequency New frequency in Hz
232 *
233 * This method calculates the phase increment needed to produce
234 * the specified frequency at the current sample rate.
235 */
236 void update_phase_increment(double frequency);
237
238 double m_saved_phase {};
239 float m_saved_frequency {};
240 float m_saved_offset {};
241 double m_saved_phase_inc {};
242 double m_saved_last_output {};
243
244 bool m_state_saved {};
245};
246}
Base class for all signal and pattern generators in Maya Flux.
std::shared_ptr< Node > m_frequency_modulator
Node that modulates the frequency.
Definition Sine.hpp:222
void set_params(float frequency, double amplitude, float offset)
Sets all basic parameters at once.
Definition Sine.hpp:147
float get_frequency() const
Gets the current base frequency.
Definition Sine.hpp:136
~Sine() override=default
Virtual destructor.
std::shared_ptr< Node > m_amplitude_modulator
Node that modulates the amplitude.
Definition Sine.hpp:227
Sinusoidal oscillator generator node.
Definition Sine.hpp:32