MayaFlux 0.5.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,
107 Buffers::VKBuffer::Usage::VERTEX,
109
110 auto writer = std::make_shared<Buffers::DataWriteProcessor>();
111 buf->set_default_processor(writer);
113
114 auto rc = config;
115
116 if (rc.vertex_shader.empty() || rc.fragment_shader.empty()) {
117 switch (rc.topology) {
120 if (rc.vertex_shader.empty())
121 rc.vertex_shader = "line.vert.spv";
122 if (rc.fragment_shader.empty())
123 rc.fragment_shader = "line.frag.spv";
124#ifndef MAYAFLUX_PLATFORM_MACOS
125 if (rc.geometry_shader.empty())
126 rc.geometry_shader = "line.geom.spv";
127#else
129#endif
130 break;
133 if (rc.vertex_shader.empty())
134 rc.vertex_shader = "triangle.vert.spv";
135 if (rc.fragment_shader.empty())
136 rc.fragment_shader = "triangle.frag.spv";
137 break;
138 default:
139 if (rc.vertex_shader.empty())
140 rc.vertex_shader = "point.vert.spv";
141 if (rc.fragment_shader.empty())
142 rc.fragment_shader = "point.frag.spv";
143 break;
144 }
145 }
146
147 auto renderer = std::make_shared<Buffers::RenderProcessor>(Buffers::ShaderConfig { rc.vertex_shader });
148 renderer->set_fragment_shader(rc.fragment_shader);
149
150 if (!rc.geometry_shader.empty())
151 renderer->set_geometry_shader(rc.geometry_shader);
152
153 renderer->set_primitive_topology(rc.topology);
154 renderer->set_polygon_mode(rc.polygon_mode);
155 renderer->set_cull_mode(rc.cull_mode);
156
157 renderer->enable_depth_test();
158 buf->set_needs_depth_attachment(true);
159
160 renderer->set_target_window(rc.target_window, buf);
161 buf->set_render_processor(renderer);
162 buf->get_processing_chain()->add_final_processor(renderer, buf);
163
164 auto& sink = sinks.emplace_back(RenderSink {
165 .buf = buf,
166 .writer = std::move(writer),
167 .renderer = std::move(renderer),
168 .fn = std::move(fn),
169 .fn_name = std::move(fn_name),
170 .window = rc.target_window,
171 });
172
173 if (!sink.fn && initial_position.has_value()) {
174 sink.writer->set_data(std::vector<Kakshya::DataVariant> {
175 Kakshya::DataVariant { std::vector<glm::vec3> { *initial_position } },
176 });
177 }
178
180 "Nexus: render sink added");
181}
182
184 std::vector<RenderSink>& sinks,
186 const std::shared_ptr<Core::Window>& window)
187{
188 auto it = std::ranges::find_if(sinks,
189 [&window](const RenderSink& s) { return s.window == window; });
190
191 if (it == sinks.end()) {
193 "Nexus: remove_render_sink called but no sink found for given window");
194 return;
195 }
196
198 sinks.erase(it);
199
201 "Nexus: render sink removed");
202}
203
204void dispatch_render_sinks(std::vector<RenderSink>& sinks, const InfluenceContext& ctx)
205{
206 for (auto& s : sinks) {
207 if (s.fn) {
208 s.fn(ctx);
209 }
210 }
211}
212
213} // 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:102
@ 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:183
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:204
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
Unified rendering configuration for graphics buffers.