MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Rigs.hpp
Go to the documentation of this file.
1#pragma once
2
5
6/**
7 * @file API/Rigs.hpp
8 * @brief Pre-assembled, purpose-built signal flow configurations.
9 *
10 * Each function in this file constructs, wires, and returns a fully built
11 * pipeline object ready for immediate use. The caller receives a live rig
12 * with no further assembly required: IO, buffering, scheduling, and output
13 * routing are resolved internally using engine globals.
14 *
15 * These are convenience entry points. Direct construction of the underlying
16 * types (SamplingPipeline, BufferPipeline, etc.) remains available for cases
17 * that require non-default configuration before build().
18 */
19
20namespace MayaFlux {
21
22namespace Kriya {
23 class SamplingPipeline;
24 class TapSetBuilder;
25 class ChimeraBuilder;
26 class BufferPipeline;
27 class CaptureBuilder;
28}
29
30namespace Kakshya {
31 class DynamicSoundStream;
32}
33
34namespace Buffers {
35 class AudioBuffer;
36 class TextureArrayBuffer;
37}
38
39namespace Yantra::Vision {
40 class VisionWorkflow;
41}
42
43/**
44 * @brief Construct a built SamplingPipeline from an audio file.
45 *
46 * Loads the file into a DynamicSoundStream via SoundFileReader::load_bounded,
47 * constructs a SamplingPipeline with engine globals (BufferManager,
48 * TaskScheduler, buffer size), calls build(), and returns the result.
49 *
50 * The returned sampler is ready for play() and play_continuous() calls.
51 * Voice slots are allocated on demand via load().
52 *
53 * @param filepath Path to the audio file (any FFmpeg-supported format).
54 * @param num_samples Number of samples to load from the file (default: 48000 * 5).
55 * @param truncate Truncate stream to num_samples if true (default: true).
56 * @param channel Output channel index (default: 0).
57 * @param max_dur_ms Optional maximum duration to build the pipeline for (in milliseconds).
58 Defaults to 0 which is infinite (the pipeline will run until the sampler is destroyed).
59 * @return Built SamplingPipeline, or nullptr if the file could not be loaded.
60 *
61 * @code
62 * auto kick = MayaFlux::create_sampler("kick.wav");
63 * kick->play(0, kick->slice_from_stream());
64 *
65 * auto pad = MayaFlux::create_sampler("pad.wav");
66 * pad->load(0, pad->slice_from_stream()).speed = 0.5;
67 * pad->play_continuous(0);
68 * @endcode
69 */
70MAYAFLUX_API std::shared_ptr<Kriya::SamplingPipeline> create_sampler(
71 const std::string& filepath, uint32_t num_samples = 48000 * 5, bool truncate = true,
72 uint32_t channel = 0, uint64_t max_dur_ms = 0);
73
74/**
75 * @brief Construct a built SamplingPipeline from a file picked in a dialog.
76 *
77 * Same as the path form, with the file chosen in a native open-file dialog.
78 *
79 * @code
80 * auto sampler = MayaFlux::create_sampler();
81 * @endcode
82 *
83 * @return Built SamplingPipeline, or nullptr if nothing was chosen or loaded.
84 */
85MAYAFLUX_API std::shared_ptr<Kriya::SamplingPipeline> create_sampler(
86 uint32_t num_samples = 48000 * 5, bool truncate = true,
87 uint32_t channel = 0, uint64_t max_dur_ms = 0);
88
89/**
90 * @brief Construct a built SamplingPipeline from an existing DynamicSoundStream.
91 *
92 * Allows multiple SamplingPipeline instances to share a single loaded stream,
93 * one per output channel, without re-reading the file. The stream is typically
94 * obtained from a previously created sampler via get_stream(), or loaded
95 * directly via get_io_manager()->load_audio_bounded().
96 *
97 * @code
98 * auto ch0 = MayaFlux::create_sampler("res/audio.wav", 48000 * 5);
99 * auto ch1 = MayaFlux::create_sampler_from_stream(ch0->get_stream(), 1);
100 * auto ch2 = MayaFlux::create_sampler_from_stream(ch0->get_stream(), 2);
101 * @endcode
102 *
103 * @param stream Loaded DynamicSoundStream to share.
104 * @param channel Output channel index (default: 0).
105 * @param max_dur_ms Optional maximum duration in milliseconds. 0 for infinite.
106 * @return Built SamplingPipeline, or nullptr if stream is null.
107 */
108MAYAFLUX_API std::shared_ptr<Kriya::SamplingPipeline> create_sampler_from_stream(
109 std::shared_ptr<Kakshya::DynamicSoundStream> stream,
110 uint32_t channel = 0, uint64_t max_dur_ms = 0);
111
112/**
113 * @brief Construct one built SamplingPipeline per channel from an audio file.
114 *
115 * Loads the file once into a shared DynamicSoundStream, then constructs one
116 * SamplingPipeline per channel. All pipelines share the same stream with no
117 * redundant IO. max_channels = 0 uses all channels available in the file.
118 *
119 * @code
120 * auto ch = MayaFlux::create_samplers("res/stereo.wav", 48000 * 5);
121 * ch[0]->play(0, ch[0]->slice_from_stream());
122 * ch[1]->play(0, ch[1]->slice_from_stream());
123 * @endcode
124 *
125 * @param filepath Path to the audio file (any FFmpeg-supported format).
126 * @param num_samples Number of samples to load (default: 48000 * 5).
127 * @param truncate Truncate stream to num_samples if true (default: true).
128 * @param max_dur_ms Optional maximum duration in milliseconds. 0 for infinite.
129 * @param max_channels Maximum channels to create pipelines for. 0 = all available.
130 * @return Vector of built SamplingPipelines, one per channel. Empty on load failure.
131 */
132MAYAFLUX_API std::vector<std::shared_ptr<Kriya::SamplingPipeline>> create_samplers(
133 const std::string& filepath, uint32_t num_samples = 48000 * 5, bool truncate = true,
134 uint64_t max_dur_ms = 0, uint32_t max_channels = 0);
135
136/**
137 * @brief Construct one built SamplingPipeline per channel from a file picked in a dialog.
138 *
139 * Same as the path form, with the file chosen in a native open-file dialog.
140 *
141 * @return One pipeline per channel. Empty if nothing was chosen or loaded.
142 */
143MAYAFLUX_API std::vector<std::shared_ptr<Kriya::SamplingPipeline>> create_samplers(
144 uint32_t num_samples = 48000 * 5, bool truncate = true,
145 uint64_t max_dur_ms = 0, uint32_t max_channels = 0);
146
147/**
148 * @brief Begin describing several taps that read one audio file.
149 *
150 * Loads the file like create_sampler and returns a builder. Each tap() adds a
151 * tap with its own entry time, speed, direction, level and channel, and
152 * start() plays them. Keep the resulting TapSet alive for as long as it should
153 * sound.
154 *
155 * @code
156 * auto taps = MayaFlux::create_tap_set("res/h.wav")
157 * .tap().speed(1.0)
158 * .tap().enters_after(2.0).speed(3.0 / 2.0).level(0.8)
159 * .tap().enters_after(4.0).speed(2.0).backward().level(0.6)
160 * .start();
161 * @endcode
162 *
163 * @param filepath Path to the audio file (any FFmpeg-supported format).
164 * @param num_samples Number of samples to load from the file (default: 48000 * 5).
165 * @param truncate Truncate stream to num_samples if true (default: true).
166 * @return Builder. If the file cannot be loaded, start() returns an empty TapSet.
167 */
169 const std::string& filepath, uint32_t num_samples = 48000 * 5, bool truncate = true);
170
171/**
172 * @brief Begin describing several taps that read a file picked in a dialog.
173 *
174 * Same as the path form, with the file chosen in a native open-file dialog.
175 *
176 * @return Builder. If nothing is chosen or loaded, start() returns an empty TapSet.
177 */
179 uint32_t num_samples = 48000 * 5, bool truncate = true);
180
181/**
182 * @brief Begin describing several taps that read an existing DynamicSoundStream.
183 *
184 * Like create_tap_set, but reads a stream already in memory, for example one
185 * shared with a sampler or filled by a recording.
186 *
187 * @param stream Source stream.
188 * @return Builder. A null stream makes start() return an empty TapSet.
189 */
191 std::shared_ptr<Kakshya::DynamicSoundStream> stream);
192
193/**
194 * @brief Begin assembling the layers of a TextureArrayBuffer from what feeds each.
195 *
196 * A layer holds a still image or file, a GPU image copied every frame, or a moment
197 * of a ring that is being recorded, read at a lag or played freely. start() begins
198 * feeding on the frame clock. Keep the resulting Chimera alive for as long as it
199 * should run.
200 *
201 * @code{.cpp}
202 * auto chimera = MayaFlux::create_chimera(array)
203 * .layer().from("res/eye.png").params({ 0.3F, 0.4F, 0.2F, 0.F })
204 * .layer().from(ring).lag(0.5).smooth().level(0.6)
205 * .start();
206 * @endcode
207 *
208 * The builder comes with a pipeline made from the engine's managers. Reach it with
209 * get_pipeline(), replace it with use_pipeline(), or record into it with record()
210 * and read its stream with from_pipeline().
211 *
212 * @param buffer Array buffer whose layers are fed.
213 * @return Builder. A null buffer makes start() return an empty Chimera.
214 */
216 std::shared_ptr<Buffers::TextureArrayBuffer> buffer);
217
218/**
219 * @brief Begin a Chimera over an array buffer made and drawn here.
220 *
221 * The buffer is made from the spec and starts to render when start() runs, after the
222 * layers' params and layer_data() are in place. Show the window after this call.
223 *
224 * @code{.cpp}
225 * auto chimera = MayaFlux::create_chimera(
226 * { .width = 1280, .height = 720, .ring_frames = 4 },
227 * { .target_window = window, .fragment_shader = "texture_array_ghost.frag" })
228 * .layer_data()
229 * .record(Kriya::BufferOperation::capture_to_stream(io, camera, 240))
230 * .layer().from_pipeline().lag(0.0)
231 * .start();
232 * @endcode
233 *
234 * @param spec Extent and format of every layer; ring_frames is the layer count.
235 * @param render How the array is drawn.
236 * @param fit How a frame of another extent is fitted, or nullopt to drop it.
237 * @return Builder.
238 */
240 const Kakshya::VideoStreamSpec& spec,
242 std::optional<Portal::Graphics::FitMode> fit = Portal::Graphics::FitMode::STRETCH);
243
244/**
245 * @brief Make a layered texture buffer that draws to a window.
246 *
247 * For writing its layers through pipeline routes or by hand. A Chimera over the
248 * result is create_chimera(buffer).
249 *
250 * @param spec Extent and format of every layer; ring_frames is the layer count.
251 * @param render How the array is drawn.
252 * @param fit How a frame of another extent is fitted, or nullopt to drop it.
253 * @param mode Mode number passed to the fragment shader.
254 * @return The buffer, already in the buffer manager.
255 */
256MAYAFLUX_API std::shared_ptr<Buffers::TextureArrayBuffer> create_texture_array(
257 const Kakshya::VideoStreamSpec& spec,
258 const Portal::Graphics::RenderConfig& render,
259 std::optional<Portal::Graphics::FitMode> fit = Portal::Graphics::FitMode::STRETCH,
260 uint32_t mode = 0);
261
262/**
263 * @brief Make a circular stream that keeps the most recent seconds of a signal.
264 *
265 * The stream runs at the engine sample rate. Fill it with record_into and read
266 * it with taps that use lag, or copy its recent past with snapshot.
267 *
268 * @param seconds How much of the past to keep.
269 * @param channels Number of channels.
270 * @return The ring, or nullptr if it would be empty.
271 */
272MAYAFLUX_API std::shared_ptr<Kakshya::DynamicSoundStream> create_ring(
273 double seconds, uint32_t channels = 1);
274
275/**
276 * @brief Record a signal into one channel of a stream, a block at a time.
277 *
278 * Captures @p source every cycle and appends each block at the stream's write
279 * head for @p channel, wrapping if the stream is a ring. A stereo ring needs a
280 * call per channel. Keep the returned pipeline alive for as long as the
281 * recording should run.
282 *
283 * @code
284 * auto ring = MayaFlux::create_ring(10.0);
285 * auto recorder = MayaFlux::record_into(ring,
286 * Kriya::BufferOperation::capture_file_from(get_io_manager(), "res/audio.wav"));
287 * auto taps = MayaFlux::create_tap_set_from_stream(ring)
288 * .tap().lag(0.05)
289 * .tap().lag(Kinesis::TimeMaps::linear(0.3, 4.0, 30.0)).level(0.6)
290 * .start();
291 * @endcode
292 *
293 * @param stream Stream to record into.
294 * @param source What to capture, for example from capture_file_from, capture_input_from or capture_from.
295 * @param channel Channel of the stream that receives the signal.
296 * @return The running pipeline, or nullptr if the stream is null.
297 */
298MAYAFLUX_API std::shared_ptr<Kriya::BufferPipeline> record_into(
299 const std::shared_ptr<Kakshya::DynamicSoundStream>& stream,
300 Kriya::CaptureBuilder source, uint32_t channel = 0);
301
302/**
303 * @brief Record a live buffer into one channel of a stream.
304 *
305 * Works for any buffer that something else already processes each cycle, such as
306 * a node buffer, a supplied buffer or an input listener. For a buffer nobody
307 * processes, pass a capture with on_capture_processing() to the other overload.
308 *
309 * @param stream Stream to record into.
310 * @param buffer Buffer to read each cycle.
311 * @param channel Channel of the stream that receives the signal.
312 * @return The running pipeline, or nullptr if the stream or buffer is null.
313 */
314MAYAFLUX_API std::shared_ptr<Kriya::BufferPipeline> record_into(
315 const std::shared_ptr<Kakshya::DynamicSoundStream>& stream,
316 const std::shared_ptr<Buffers::AudioBuffer>& buffer, uint32_t channel = 0);
317
318/**
319 * @brief Record several sources into consecutive channels of a stream.
320 *
321 * Source i goes to channel i, so a stereo ring is two sources. Each source gets
322 * its own pipeline, because one pipeline spends a cycle per capture.
323 *
324 * @param stream Stream to record into.
325 * @param sources What to capture, one per channel starting at channel 0.
326 * @return One running pipeline per source, in order. Empty if the stream is null.
327 */
328MAYAFLUX_API std::vector<std::shared_ptr<Kriya::BufferPipeline>> record_into(
329 const std::shared_ptr<Kakshya::DynamicSoundStream>& stream,
330 std::vector<Kriya::CaptureBuilder> sources);
331
332/**
333 * @brief A vision workflow running on the engine's managers.
334 *
335 * Its live runs stop when the returned workflow is destroyed. Include
336 * WorkflowIncludes.hpp to call it.
337 *
338 * @code
339 * auto vision = MayaFlux::create_vision_workflow();
340 * auto edges = vision->process_to_buffer({
341 * .source = camera,
342 * .query = { .intents = VisionIntent::DetectEdges },
343 * .extract = VisionExtractMode::Edges,
344 * .render = { .target_window = window },
345 * });
346 * @endcode
347 */
348MAYAFLUX_API std::shared_ptr<Yantra::Vision::VisionWorkflow> create_vision_workflow();
349
350} // namespace MayaFlux
Core::GlobalStreamInfo stream
Definition Config.cpp:40
std::shared_ptr< NetworkGeometryBuffer > buffer
uint32_t mode
uint32_t channels
Fluent builder interface for constructing BufferCapture configurations.
Definition Capture.hpp:249
Declares the layers of a Chimera, in order, and starts feeding them.
Definition Chimera.hpp:190
Describes a tap set one tap at a time, then starts it.
Definition TapSet.hpp:119
@ Buffers
Buffers, Managers, processors and processing chains.
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
@ Kriya
Automatable tasks and fluent scheduling api for Nodes and Buffers.
@ STRETCH
Whole source onto whole destination, aspect ignored.
Kriya::ChimeraBuilder create_chimera(std::shared_ptr< Buffers::TextureArrayBuffer > buffer)
Begin assembling the layers of a TextureArrayBuffer from what feeds each.
Definition Rigs.cpp:167
Kriya::TapSetBuilder create_tap_set(const std::string &filepath, uint32_t num_samples, bool truncate)
Begin describing several taps that read one audio file.
Definition Rigs.cpp:135
std::shared_ptr< Kriya::SamplingPipeline > create_sampler(const std::string &filepath, uint32_t num_samples, bool truncate, uint32_t channel, uint64_t max_dur_ms)
Construct a built SamplingPipeline from an audio file.
Definition Rigs.cpp:20
std::shared_ptr< Yantra::Vision::VisionWorkflow > create_vision_workflow()
A vision workflow running on the engine's managers.
Definition Rigs.cpp:262
std::shared_ptr< Kakshya::DynamicSoundStream > create_ring(double seconds, uint32_t channels)
Make a circular stream that keeps the most recent seconds of a signal.
Definition Rigs.cpp:199
std::shared_ptr< Kriya::SamplingPipeline > create_sampler_from_stream(std::shared_ptr< Kakshya::DynamicSoundStream > stream, uint32_t channel, uint64_t max_dur_ms)
Construct a built SamplingPipeline from an existing DynamicSoundStream.
Definition Rigs.cpp:48
std::vector< std::shared_ptr< Kriya::SamplingPipeline > > create_samplers(const std::string &filepath, uint32_t num_samples, bool truncate, uint64_t max_dur_ms, uint32_t max_channels)
Construct one built SamplingPipeline per channel from an audio file.
Definition Rigs.cpp:106
std::shared_ptr< Kriya::BufferPipeline > record_into(const std::shared_ptr< Kakshya::DynamicSoundStream > &stream, Kriya::CaptureBuilder source, uint32_t channel)
Record a signal into one channel of a stream, a block at a time.
Definition Rigs.cpp:215
std::shared_ptr< Buffers::TextureArrayBuffer > create_texture_array(const Kakshya::VideoStreamSpec &spec, const Portal::Graphics::RenderConfig &render, std::optional< Portal::Graphics::FitMode > fit, uint32_t mode)
Make a layered texture buffer that draws to a window.
Definition Rigs.cpp:185
Kriya::TapSetBuilder create_tap_set_from_stream(std::shared_ptr< Kakshya::DynamicSoundStream > stream)
Begin describing several taps that read an existing DynamicSoundStream.
Definition Rigs.cpp:160
Main namespace for the Maya Flux audio engine.
Definition Runtime.cpp:12
Describes a DynamicVideoStream so it can be built by designated initializer.
Unified rendering configuration for graphics buffers.