MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ process_batch()

void MayaFlux::Nodes::Network::ResonatorNetwork::process_batch ( unsigned int  num_samples)
overridevirtual

Processes num_samples through all resonators and accumulates output.

Parameters
num_samplesNumber of audio samples to compute

For each sample, each resonator draws from its individual exciter (or the network-level exciter, or zero if none) and processes one sample. All resonator outputs are summed and RMS-normalised (divided by sqrt(resonator_count)) into m_last_audio_buffer before set_output_scale() is applied.

Implements MayaFlux::Nodes::Network::NodeNetwork.

Definition at line 179 of file ResonatorNetwork.cpp.

180{
181 if (m_resonators.empty()) {
182 while (m_audio_buffer_lock.test_and_set(std::memory_order_acquire))
183 std::this_thread::yield();
184
185 m_last_audio_buffer.assign(num_samples, 0.0);
186 m_audio_buffer_lock.clear(std::memory_order_release);
187 return;
188 }
189
191
192 thread_local std::vector<double> scratch;
193 scratch.assign(num_samples, 0.0);
194
195 const double norm = m_norm_factor.load(std::memory_order_acquire);
196
197 m_node_buffers.resize(m_resonators.size());
198 for (auto& nb : m_node_buffers) {
199 nb.clear();
200 nb.reserve(num_samples);
201 }
202
203 thread_local std::vector<std::optional<std::span<const double>>> net_exc_bufs;
204 net_exc_bufs.clear();
205 if (m_network_exciter) {
206 net_exc_bufs.reserve(m_resonators.size());
207 for (size_t ri = 0; ri < m_resonators.size(); ++ri)
208 net_exc_bufs.push_back(m_network_exciter->get_node_audio_buffer(ri));
209 }
210
211 for (size_t s = 0; s < num_samples; ++s) {
212 for (size_t ri = 0; ri < m_resonators.size(); ++ri) {
213 auto& r = m_resonators[ri];
214 double excitation = 0.0;
215
216 if (r.exciter) {
217 excitation = r.exciter->process_sample(0.0);
218 } else if (!net_exc_bufs.empty() && net_exc_bufs[ri] && s < net_exc_bufs[ri]->size()) {
219 excitation = (*net_exc_bufs[ri])[s];
220 } else if (m_exciter) {
221 excitation = m_exciter->process_sample(0.0);
222 }
223
224 const double out = r.filter->process_sample(excitation) * r.gain;
225 r.last_output = out;
226 m_node_buffers[ri].push_back(out);
227 scratch[s] += out * norm;
228 }
229 }
230
231 while (m_audio_buffer_lock.test_and_set(std::memory_order_acquire))
232 std::this_thread::yield();
233
234 m_last_audio_buffer.assign(scratch.begin(), scratch.end());
236 m_audio_buffer_lock.clear(std::memory_order_release);
237}
std::vector< float > * out
void apply_output_scale()
Apply m_output_scale to m_last_audio_buffer.
std::atomic_flag m_audio_buffer_lock
Spinlock guarding m_last_audio_buffer.
std::vector< double > m_last_audio_buffer
std::atomic< double > m_norm_factor
Normalisation factor for summed output, rms scaled by number of active resonators.
std::vector< std::vector< double > > m_node_buffers
Per-resonator sample buffers populated each process_batch()
std::shared_ptr< Node > m_exciter
networ-level shared exciter (may be nullptr)
void update_mapped_parameters()
Apply all registered parameter mappings for the current cycle.
std::shared_ptr< NodeNetwork > m_network_exciter
Optional NodeNetwork exciter for ONE_TO_ONE mapping (may be nullptr)

References MayaFlux::Nodes::Network::NodeNetwork::apply_output_scale(), MayaFlux::Nodes::Network::NodeNetwork::m_audio_buffer_lock, m_exciter, MayaFlux::Nodes::Network::NodeNetwork::m_last_audio_buffer, m_network_exciter, m_node_buffers, m_norm_factor, m_resonators, out, and update_mapped_parameters().

+ Here is the call graph for this function: