Processes output data for audio interface.
Processes node graph and buffer operations, then fills the output buffer with processed audio data in interleaved format for the audio interface. This is the main processing entry point called by audio callbacks.
63{
65
66 if (output_buffer == nullptr) {
68 "No output available");
70 return 1;
71 }
72
74 if (output_buffer) {
76 std::memset(output_buffer, 0, total_samples * sizeof(double));
77 }
79 return 0;
80 }
81
84 "Invalid processing handle");
86 return 1;
87 }
88
89 try {
91 size_t total_samples = static_cast<size_t>(num_frames) * num_channels;
92 std::span<double> output_span(output_buffer, total_samples);
93
94 std::vector<std::span<const double>> buffer_data(num_channels);
95 std::vector<std::vector<std::vector<double>>> all_network_outputs(num_channels);
96 bool has_underrun = false;
97
99
100 for (uint32_t channel = 0; channel < num_channels; channel++) {
103
105
106 if (channel_data.size() < num_frames) {
108 "Channel buffer underrun");
109 has_underrun = true;
110
111 buffer_data[channel] = std::span<const double>();
112 } else {
113 buffer_data[channel] = channel_data;
114 }
115 }
116
117 for (size_t i = 0; i < num_frames; ++i) {
118
120
121 for (size_t j = 0; j < num_channels; ++j) {
122 double buffer_sample = 0.0;
123 if (!buffer_data[j].empty() && i < buffer_data[j].size()) {
124 buffer_sample = buffer_data[j][i];
125 }
126
128
129 for (const auto& network_buffer : all_network_outputs[j]) {
130 if (i < network_buffer.size()) {
131 sample += network_buffer[i];
132 }
133 }
134
135 size_t index = i * num_channels + j;
136 output_span[index] = std::clamp(sample, -1., 1.);
137 }
138 }
139
141 return has_underrun ? 1 : 0;
142
143 } catch (const std::exception& e) {
145 "Exception during audio output processing: {}", e.what());
146
147 if (output_buffer) {
149 std::memset(output_buffer, 0, total_samples * sizeof(double));
150 }
151
153 return 1;
154 }
155}
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
std::atomic< int > m_callback_active
Active callback counter.
std::atomic< bool > m_is_running
Subsystem running state.
GlobalStreamInfo m_stream_info
Audio stream configuration.
SubsystemProcessingHandle * m_handle
Reference to processing handle.
std::span< const double > read_channel_data(uint32_t channel) const
Get read-only access to channel data.
void process_channel(uint32_t channel, uint32_t processing_units)
Process specific channel.
std::vector< std::vector< double > > process_audio_networks(uint32_t num_samples, uint32_t channel=0)
double process_sample(uint32_t channel)
TaskSchedulerHandle tasks
NodeProcessingHandle nodes
Node processing interface.
BufferProcessingHandle buffers
Buffer processing interface.
void process_buffer_cycle()
Process all tasks scheduled for current buffer cycle.
void process(uint64_t processing_units)
Process all tasks in token domain.
@ AudioCallback
Audio callback thread - strictest real-time requirements.
@ Core
Core engine, backend, subsystems.
uint32_t channels
Number of discrete channels in this set.
ChannelConfig output
Configuration for output signal channels.