MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Tasks.cpp
Go to the documentation of this file.
1#include "Tasks.hpp"
5
7
9
10namespace MayaFlux::Kriya {
11
12std::shared_ptr<Vruta::Routine> metro(double interval_seconds, std::function<void()> callback, Vruta::ProcessingToken token)
13{
15 auto coro = [](double interval, std::function<void()> cb) -> Vruta::GraphicsRoutine {
16 uint64_t units = Vruta::seconds_to_frames(interval);
17 if (units < 1) {
19 "metro interval {}s is shorter than one frame, clamping to 1 frame", interval);
20 }
21 units = std::max<uint64_t>(1, units);
22 auto& p = co_await GetGraphicsPromise {};
23 while (!p.should_terminate) {
24 cb();
25 co_await FrameDelay { .frames_to_wait = units };
26 }
27 };
28 return std::make_shared<Vruta::GraphicsRoutine>(coro(interval_seconds, std::move(callback)));
29 }
30 auto coro = [](double interval, std::function<void()> cb) -> Vruta::SoundRoutine {
31 uint64_t units = Vruta::seconds_to_samples(interval);
32 if (units < 1) {
34 "metro interval {}s is shorter than one sample, clamping to 1 sample", interval);
35 }
36 units = std::max<uint64_t>(1, units);
37 auto& p = co_await GetAudioPromise {};
38 while (!p.should_terminate) {
39 cb();
40 co_await SampleDelay { units };
41 }
42 };
43 return std::make_shared<Vruta::SoundRoutine>(coro(interval_seconds, std::move(callback)));
44}
45
46std::shared_ptr<Vruta::Routine> sequence(std::vector<std::pair<double, std::function<void()>>> sequence, Vruta::ProcessingToken token)
47{
49 auto coro = [](std::vector<std::pair<double, std::function<void()>>> seq) -> Vruta::GraphicsRoutine {
50 for (const auto& [time, cb] : seq) {
52 cb();
53 }
54 };
55 return std::make_shared<Vruta::GraphicsRoutine>(coro(std::move(sequence)));
56 }
57 auto coro = [](std::vector<std::pair<double, std::function<void()>>> seq) -> Vruta::SoundRoutine {
58 for (const auto& [time, cb] : seq) {
59 co_await SampleDelay { Vruta::seconds_to_samples(time) };
60 cb();
61 }
62 };
63 return std::make_shared<Vruta::SoundRoutine>(coro(std::move(sequence)));
64}
65
66Vruta::SoundRoutine line(float start_value, float end_value, float duration_seconds, uint32_t step_duration, bool restartable)
67{
68 auto& promise_ref = co_await GetAudioPromise {};
69
70 promise_ref.set_state("current_value", start_value);
71 promise_ref.set_state("end_value", end_value);
72 promise_ref.set_state("restart", false);
73
74 const unsigned int sample_rate = Vruta::s_registered_sample_rate;
75 if (step_duration < 1) {
76 step_duration = 1;
77 }
78
79 uint64_t total_samples = static_cast<uint64_t>(static_cast<double>(duration_seconds) * sample_rate);
80 float per_sample_step = (end_value - start_value) / (float)total_samples;
81 float sample_step = per_sample_step * (float)step_duration;
82
83 promise_ref.set_state("step", sample_step);
84
85 for (;;) {
86 auto current_value = promise_ref.get_state<float>("current_value");
87 auto last_value = promise_ref.get_state<float>("end_value");
88 auto step = promise_ref.get_state<float>("step");
89
90 if (!current_value || !last_value || !step) {
91 MF_ERROR(Journal::Component::Kriya, Journal::Context::CoroutineScheduling, "Line task state not properly initialized");
92 co_return;
93 }
94
95 *current_value = start_value;
96
97 uint64_t samples_elapsed = 0;
98
99 co_await SampleDelay { 1 };
100
101 while (samples_elapsed < total_samples) {
102 *current_value += *step;
103
104 if ((*step > 0 && *current_value >= *last_value) || (*step < 0 && *current_value <= *last_value)) {
105 *current_value = *last_value;
106 }
107
108 samples_elapsed += step_duration;
109 co_await SampleDelay { step_duration };
110 }
111
112 if (!restartable)
113 break;
114
115 auto restart_requested = promise_ref.get_state<bool>("restart");
116 if (restart_requested && *restart_requested) {
117 *restart_requested = false;
118 continue;
119 }
120
121 promise_ref.auto_resume = false;
122 co_await std::suspend_always {};
123 }
124}
125
127 std::function<void()> callback,
128 std::shared_ptr<Nodes::Generator::Logic> logic_node,
129 bool open)
130{
131 auto& promise_ref = co_await GetAudioPromise {};
132
133 if (!logic_node) {
134 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
135 }
136
137 if (open) {
138 logic_node->while_true([callback](const Nodes::NodeContext& /*ctx*/) {
139 callback();
140 });
141 } else {
142 logic_node->while_false([callback](const Nodes::NodeContext& /*ctx*/) {
143 callback();
144 });
145 }
146
147 while (true) {
148 if (promise_ref.should_terminate) {
149 break;
150 }
151
152 logic_node->process_sample(0.0);
153
154 co_await SampleDelay { 1 };
155 }
156}
157
159 bool target_state,
160 std::function<void()> callback,
161 std::shared_ptr<Nodes::Generator::Logic> logic_node)
162{
163 auto& promise_ref = co_await GetAudioPromise {};
164
165 if (!logic_node) {
166 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
167 }
168
169 logic_node->on_change_to(target_state,
170 [callback](const Nodes::NodeContext& /*ctx*/) {
171 callback();
172 });
173
174 while (true) {
175 if (promise_ref.should_terminate) {
176 break;
177 }
178
179 logic_node->process_sample(0.0);
180
181 co_await SampleDelay { 1 };
182 }
183}
184
186 std::function<void()> callback,
187 std::shared_ptr<Nodes::Generator::Logic> logic_node)
188{
189 auto& promise_ref = co_await GetAudioPromise {};
190
191 if (!logic_node) {
192 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
193 }
194
195 logic_node->on_change([callback](const Nodes::NodeContext& /*ctx*/) {
196 callback();
197 });
198
199 while (true) {
200 if (promise_ref.should_terminate) {
201 break;
202 }
203
204 logic_node->process_sample(0.0);
205
206 co_await SampleDelay { 1 };
207 }
208}
209}
#define MF_ERROR(comp, ctx,...)
#define MF_RT_WARN(comp, ctx,...)
PickCallback callback
Definition Picker.cpp:22
Base context class for node callbacks.
Definition Node.hpp:53
A C++20 coroutine-based graphics processing task with frame-accurate timing.
Definition Routine.hpp:512
A C++20 coroutine-based audio processing task with sample-accurate timing.
Definition Routine.hpp:327
@ CoroutineScheduling
Coroutine scheduling and temporal coordination (Vruta::TaskScheduler)
@ Kriya
Automatable tasks and fluent scheduling api for Nodes and Buffers.
Vruta::SoundRoutine Gate(std::function< void()> callback, std::shared_ptr< Nodes::Generator::Logic > logic_node, bool open)
Coroutine that executes callback continuously while logic node outputs true.
Definition Tasks.cpp:126
Vruta::SoundRoutine Toggle(std::function< void()> callback, std::shared_ptr< Nodes::Generator::Logic > logic_node)
Coroutine that executes callback on any logic node state change.
Definition Tasks.cpp:185
Vruta::SoundRoutine line(float start_value, float end_value, float duration_seconds, uint32_t step_duration, bool restartable)
Creates a continuous interpolation generator between two values over time.
Definition Tasks.cpp:66
std::shared_ptr< Vruta::Routine > sequence(std::vector< std::pair< double, std::function< void()> > > sequence, Vruta::ProcessingToken token)
Creates a temporal sequence that executes callbacks at specified time offsets.
Definition Tasks.cpp:46
Vruta::SoundRoutine Trigger(bool target_state, std::function< void()> callback, std::shared_ptr< Nodes::Generator::Logic > logic_node)
Coroutine that executes callback when logic node changes to specific state.
Definition Tasks.cpp:158
std::shared_ptr< Vruta::Routine > metro(double interval_seconds, std::function< void()> callback, Vruta::ProcessingToken token)
Creates a periodic event generator that executes a callback at regular intervals.
Definition Tasks.cpp:12
uint64_t seconds_to_samples(double seconds, uint32_t sample_rate=s_registered_sample_rate)
Convert seconds to samples at a given sample rate.
@ FRAME_ACCURATE
Coroutine is frame-accurate.
MAYAFLUX_API uint32_t s_registered_sample_rate
Definition Clock.cpp:9
uint64_t seconds_to_frames(double seconds, uint32_t frame_rate=s_registered_frame_rate)
Convert seconds to frames at a given frame rate.
graphics-domain awaiter for frame-accurate timing delays
Templated awaitable for accessing a coroutine's promise object.
Awaitable object for precise sample-accurate timing delays.