MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Sinks.cpp
Go to the documentation of this file.
1#include "Sinks.hpp"
2
9
11
12namespace MayaFlux::Nexus {
13
14// =============================================================================
15// Audio
16// =============================================================================
17
19 std::vector<AudioSink>& sinks,
21 uint32_t channel,
22 std::function<Kakshya::DataVariant(const InfluenceContext&)> fn,
23 std::string fn_name)
24{
25 auto buf = std::make_shared<Buffers::AudioBuffer>(channel, Buffers::s_preferred_buffer_size);
26 auto writer = std::make_shared<Buffers::AudioWriteProcessor>();
27 buf->set_default_processor(writer);
28
30
31 sinks.push_back(AudioSink {
32 .buf = std::move(buf),
33 .writer = std::move(writer),
34 .fn = std::move(fn),
35 .fn_name = std::move(fn_name),
36 .channel = channel,
37 });
38
40 "Nexus: audio sink added on channel {}", channel);
41}
42
44 std::vector<AudioSink>& sinks,
46 uint32_t channel)
47{
48 auto it = std::ranges::find_if(sinks,
49 [channel](const AudioSink& s) { return s.channel == channel; });
50
51 if (it == sinks.end()) {
53 "Nexus: remove_audio_sink called for channel {} but no sink found", channel);
54 return;
55 }
56
58 sinks.erase(it);
59
61 "Nexus: audio sink removed from channel {}", channel);
62}
63
64void push_audio_data(std::vector<AudioSink>& sinks, std::span<const double> samples)
65{
66 for (auto& s : sinks) {
67 s.writer->set_data(samples);
68 }
69}
70
71void dispatch_audio_sinks(std::vector<AudioSink>& sinks, const InfluenceContext& ctx)
72{
73 for (auto& s : sinks) {
74 if (!s.fn) {
75 continue;
76 }
77 auto variant = s.fn(ctx);
78
79 if (auto* vec = std::get_if<std::vector<double>>(&variant)) {
80 s.writer->set_data(std::span<const double>(*vec));
81 } else {
82 Kakshya::EigenAccess acc(variant);
83 const Eigen::VectorXd v = acc.to_vector();
84 std::vector<double> samples(static_cast<size_t>(v.size()));
85 Eigen::Map<Eigen::VectorXd>(samples.data(), v.size()) = v;
86 s.writer->set_data(std::span<const double>(samples));
87 }
88 }
89}
90
91// =============================================================================
92// Render
93// =============================================================================
94
96 std::vector<RenderSink>& sinks,
99 RenderFn fn,
100 std::string fn_name,
101 const std::optional<glm::vec3>& initial_position)
102{
103 constexpr size_t k_initial_bytes = 4096;
104
105 auto buf = std::make_shared<Buffers::VKBuffer>(
106 k_initial_bytes,
109
110 auto writer = std::make_shared<Buffers::DataWriteProcessor>();
111 buf->set_default_processor(writer);
113
114 std::string vert = config.vertex_shader;
115 std::string frag = config.fragment_shader;
116 std::string geom = config.geometry_shader;
117
118 if (vert.empty() || frag.empty()) {
119 switch (config.topology) {
122 if (frag.empty())
123 frag = "line.frag.spv";
124#ifndef MAYAFLUX_PLATFORM_MACOS
125 if (vert.empty())
126 vert = "line.vert.spv";
127 if (geom.empty())
128 geom = "line.geom.spv";
129#else
130 if (vert.empty())
131 vert = "line_fallback.vert.spv";
132#endif
133 break;
136 if (vert.empty())
137 vert = "triangle.vert.spv";
138 if (frag.empty())
139 frag = "triangle.frag.spv";
140 break;
141 default:
142 if (vert.empty())
143 vert = "point.vert.spv";
144 if (frag.empty())
145 frag = "point.frag.spv";
146 break;
147 }
148 }
149
150 auto renderer = std::make_shared<Buffers::RenderProcessor>(Buffers::ShaderConfig { vert });
151 renderer->set_fragment_shader(frag);
152
153 if (!geom.empty())
154 renderer->set_geometry_shader(geom);
155
156 renderer->set_primitive_topology(config.topology);
157 renderer->set_polygon_mode(config.polygon_mode);
158 renderer->set_cull_mode(config.cull_mode);
159
160 renderer->enable_depth_test();
161 buf->set_needs_depth_attachment(true);
162
163 renderer->set_target_window(config.target_window, buf);
164 buf->set_render_processor(renderer);
165 buf->get_processing_chain()->add_final_processor(renderer, buf);
166
167 auto& sink = sinks.emplace_back(RenderSink {
168 .buf = buf,
169 .writer = std::move(writer),
170 .renderer = std::move(renderer),
171 .fn = std::move(fn),
172 .fn_name = std::move(fn_name),
173 .window = config.target_window,
174 });
175
176 if (!sink.fn && initial_position.has_value()) {
177 sink.writer->set_data(std::vector<Kakshya::DataVariant> {
178 Kakshya::DataVariant { std::vector<glm::vec3> { *initial_position } },
179 });
180 }
181
183 "Nexus: render sink added");
184}
185
187 std::vector<RenderSink>& sinks,
189 const std::shared_ptr<Core::Window>& window)
190{
191 auto it = std::ranges::find_if(sinks,
192 [&window](const RenderSink& s) { return s.window == window; });
193
194 if (it == sinks.end()) {
196 "Nexus: remove_render_sink called but no sink found for given window");
197 return;
198 }
199
201 sinks.erase(it);
202
204 "Nexus: render sink removed");
205}
206
207void dispatch_render_sinks(std::vector<RenderSink>& sinks, const InfluenceContext& ctx)
208{
209 for (auto& s : sinks) {
210 if (s.fn) {
211 s.fn(ctx);
212 }
213 }
214}
215
216} // namespace MayaFlux::Nexus
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void remove_buffer(const std::shared_ptr< Buffer > &buffer, ProcessingToken token, uint32_t channel=0)
Removes a buffer from a token.
void add_buffer(const std::shared_ptr< Buffer > &buffer, ProcessingToken token, uint32_t channel=0)
Adds a buffer to a token and channel.
Token-based multimodal buffer management system for unified data stream processing.
Eigen::VectorXd to_vector() const
Convert DataVariant to Eigen column vector.
Type-erased accessor for converting DataVariant to Eigen types.
uint32_t s_preferred_buffer_size
Global default buffer size.
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ Init
Engine/subsystem initialization.
@ Buffers
Buffers, Managers, processors and processing chains.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:76
@ VERTICES_3D
3D vertex data (positions, normals, etc.)
std::function< void(const InfluenceContext &)> RenderFn
Definition Sinks.hpp:26
void remove_render_sink(std::vector< RenderSink > &sinks, Buffers::BufferManager &mgr, const std::shared_ptr< Core::Window > &window)
Unregister and destroy the render sink targeting window.
Definition Sinks.cpp:186
void dispatch_render_sinks(std::vector< RenderSink > &sinks, const InfluenceContext &ctx)
For each sink that has a producer fn, call it and push the result.
Definition Sinks.cpp:207
void push_audio_data(std::vector< AudioSink > &sinks, std::span< const double > samples)
Push samples to every audio sink in sinks.
Definition Sinks.cpp:64
void dispatch_audio_sinks(std::vector< AudioSink > &sinks, const InfluenceContext &ctx)
For each sink that has a producer fn, call it and push the result.
Definition Sinks.cpp:71
void add_audio_sink(std::vector< AudioSink > &sinks, Buffers::BufferManager &mgr, uint32_t channel, std::function< Kakshya::DataVariant(const InfluenceContext &)> fn, std::string fn_name)
Create and register an audio sink on channel.
Definition Sinks.cpp:18
void add_render_sink(std::vector< RenderSink > &sinks, Buffers::BufferManager &mgr, const Portal::Graphics::RenderConfig &config, RenderFn fn, std::string fn_name, const std::optional< glm::vec3 > &initial_position)
Create and register a render sink targeting window.
Definition Sinks.cpp:95
void remove_audio_sink(std::vector< AudioSink > &sinks, Buffers::BufferManager &mgr, uint32_t channel)
Unregister and destroy the audio sink on channel.
Definition Sinks.cpp:43
std::shared_ptr< Buffers::AudioBuffer > buf
Definition Sinks.hpp:41
Holds the plumbing for one audio output registered from a Nexus object.
Definition Sinks.hpp:40
Data passed to an Emitter or Agent influence function on each commit.
std::shared_ptr< Core::Window > window
Definition Sinks.hpp:69
std::shared_ptr< Buffers::VKBuffer > buf
Definition Sinks.hpp:64
Holds the plumbing for one graphics output registered from a Nexus object.
Definition Sinks.hpp:63
std::shared_ptr< Core::Window > target_window
Unified rendering configuration for graphics buffers.