MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
LogicProcessor.cpp
Go to the documentation of this file.
1#include "LogicProcessor.hpp"
2
4
5namespace MayaFlux::Buffers {
6
8 const std::shared_ptr<Nodes::Generator::Logic>& logic,
9 bool reset_between_buffers)
10 : m_logic(logic)
11 , m_reset_between_buffers(reset_between_buffers)
12 , m_use_internal(false)
13 , m_modulation_type(ModulationType::REPLACE)
14 , m_has_generated_data(false)
15 , m_high_value(1.0)
16 , m_low_value(0.0)
17 , m_last_held_value(0.0)
18 , m_last_logic_value(0.0)
19{
20}
21
22bool LogicProcessor::generate(size_t num_samples, const std::vector<double>& input_data)
23{
24 if (!m_logic || input_data.empty()) {
25 return false;
26 }
27
28 if (m_pending_logic) {
30 m_pending_logic.reset();
31 m_use_internal = true;
32 }
33
34 m_logic_data.resize(num_samples, 0);
35
36 std::vector<double> data = input_data;
37 if (data.size() < num_samples) {
38 data.resize(num_samples, 0.0);
39 }
40
42 m_logic->reset();
43 }
44
45 const auto& state = m_logic->m_state.load();
46
47 if (state == Utils::NodeState::INACTIVE) {
48 for (size_t i = 0; i < data.size(); ++i) {
49 m_logic_data[i] = m_logic->process_sample(data[i]);
50 }
51 } else {
52 m_logic->save_state();
53 for (size_t i = 0; i < data.size(); ++i) {
54 m_logic_data[i] = m_logic->process_sample(data[i]);
55 }
56 m_logic->restore_state();
57 }
58
60 return true;
61}
62
63bool LogicProcessor::apply(const std::shared_ptr<Buffer>& buffer, ModulationFunction modulation_func)
64{
65 if (!buffer || !m_has_generated_data) {
66 return false;
67 }
68
69 auto& buffer_data = std::dynamic_pointer_cast<AudioBuffer>(buffer)->get_data();
70 size_t min_size = std::min(m_logic_data.size(), buffer_data.size());
71
72 if (!modulation_func) {
73 switch (m_modulation_type) {
75 modulation_func = [](double logic_val, double /*buffer_val*/) {
76 return logic_val;
77 };
78 break;
79
81 modulation_func = [](double logic_val, double buffer_val) {
82 return logic_val * buffer_val;
83 };
84 break;
85
87 modulation_func = [](double logic_val, double buffer_val) {
88 return logic_val + buffer_val;
89 };
90 break;
91
93 modulation_func = [](double logic_val, double buffer_val) {
94 return logic_val > 0.5 ? -buffer_val : buffer_val;
95 };
96 break;
97
99 if (min_size > 0) {
100 m_last_held_value = buffer_data[0];
101 }
102
103 modulation_func = [this](double logic_val, double buffer_val) mutable {
104 if (logic_val > 0.5) {
105 m_last_held_value = buffer_val;
106 return buffer_val;
107 }
108 return m_last_held_value;
109 };
110 break;
111
113 modulation_func = [](double logic_val, double buffer_val) {
114 return logic_val > 0.5 ? buffer_val : 0.0;
115 };
116 break;
117
119 modulation_func = [](double logic_val, double buffer_val) {
120 return buffer_val * logic_val;
121 };
122 break;
123
125 modulation_func = [this](double logic_val, double /*buffer_val*/) {
126 return logic_val > 0.5 ? m_high_value : m_low_value;
127 };
128 break;
129
131 if (min_size > 0) {
132 m_last_held_value = buffer_data[0];
134 }
135
136 modulation_func = [this, first_sample = true](double logic_val, double buffer_val) mutable {
137 if (first_sample) {
138 first_sample = false;
139 return buffer_val;
140 }
141
142 bool logic_changed = std::abs(logic_val - m_last_logic_value) > 0.01;
143 m_last_logic_value = logic_val;
144
145 if (logic_changed) {
146 m_last_held_value = buffer_val;
147 }
148 return m_last_held_value;
149 };
150 break;
151
153 modulation_func = m_modulation_function;
154 break;
155
156 default:
157 modulation_func = [](double logic_val, double /*buffer_val*/) {
158 return logic_val;
159 };
160 }
161 }
162
163 for (size_t i = 0; i < min_size; ++i) {
164 buffer_data[i] = modulation_func(m_logic_data[i], buffer_data[i]);
165 }
166
167 return true;
168}
169
170void LogicProcessor::processing_function(std::shared_ptr<Buffer> buffer)
171{
172 if (!m_logic || !buffer) {
173 return;
174 }
175
176 auto audio_buffer = std::dynamic_pointer_cast<AudioBuffer>(buffer);
177 if (!audio_buffer || audio_buffer->get_data().empty()) {
178 return;
179 }
180
181 generate(audio_buffer->get_num_samples(), audio_buffer->get_data());
182 apply(buffer);
183}
184
185void LogicProcessor::on_attach(std::shared_ptr<Buffer> /*buffer*/)
186{
187 if (m_logic) {
188 m_logic->reset();
189 }
190
191 m_last_held_value = 0.0;
192 m_last_logic_value = 0.0;
193}
194
200
201} // namespace MayaFlux::Buffers
void processing_function(std::shared_ptr< Buffer > buffer) override
Processes a buffer through the logic node.
ModulationFunction m_modulation_function
Custom transformation function.
LogicProcessor(Args &&... args)
Constructs a LogicProcessor with internal Logic node.
ModulationType
Defines how logic values modulate buffer content.
@ MULTIPLY
Gate/mask buffer: out = logic * buffer (standard audio gate)
@ SAMPLE_AND_HOLD
Sample on logic change: out = logic_changed ? buffer : held_value.
@ REPLACE
Replace buffer with logic values: out = logic.
@ CUSTOM
User-defined modulation function.
@ ZERO_ON_FALSE
Silence when logic is false: out = logic ? buffer : 0.0.
@ INVERT_ON_TRUE
Invert signal when logic is true: out = logic ? -buffer : buffer.
@ ADD
Offset buffer: out = logic + buffer.
@ CROSSFADE
Smooth interpolation: out = lerp(0.0, buffer, logic)
@ HOLD_ON_FALSE
Hold last value when logic is false: out = logic ? buffer : last_value.
@ THRESHOLD_REMAP
Binary value selection: out = logic ? high_val : low_val.
std::vector< double > m_logic_data
Stored logic processing results.
bool m_has_generated_data
Whether logic data has been generated.
double m_last_held_value
Last held value for HOLD_ON_FALSE and SAMPLE_AND_HOLD.
double m_high_value
High value for THRESHOLD_REMAP.
std::function< double(double, double)> ModulationFunction
Function type for custom digital signal transformations.
bool generate(size_t num_samples, const std::vector< double > &input_data)
Generates discrete logic data from input without modifying any buffer.
double m_low_value
Low value for THRESHOLD_REMAP.
std::shared_ptr< Nodes::Generator::Logic > m_logic
Logic node for processing.
double m_last_logic_value
Previous logic value for change detection.
ModulationType m_modulation_type
How logic values modulate buffer content.
void set_modulation_function(ModulationFunction func)
Set custom modulation function.
std::shared_ptr< Nodes::Generator::Logic > m_pending_logic
Pending logic node update.
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when the processor is attached to a buffer.
bool m_use_internal
Whether to use internal logic node.
bool apply(const std::shared_ptr< Buffer > &buffer, ModulationFunction modulation_func=nullptr)
Applies stored logic data to the given buffer.
bool m_reset_between_buffers
Whether to reset logic between buffers.
@ INACTIVE
Engine is not processing this node.
Definition Utils.hpp:29