MayaFlux 0.4.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
8namespace MayaFlux::Kriya {
9
10Vruta::SoundRoutine metro(Vruta::TaskScheduler& scheduler, double interval_seconds, std::function<void()> callback)
11{
12 uint64_t interval_samples = scheduler.seconds_to_samples(interval_seconds);
13 auto& promise = co_await Kriya::GetAudioPromise {};
14
15 while (true) {
16 if (promise.should_terminate) {
17 break;
18 }
19 callback();
20 co_await SampleDelay(interval_samples);
21 }
22}
23
24Vruta::SoundRoutine sequence(Vruta::TaskScheduler& scheduler, std::vector<std::pair<double, std::function<void()>>> sequence)
25{
26 for (const auto& [time, callback] : sequence) {
27 uint64_t delay_samples = scheduler.seconds_to_samples(time);
28 co_await SampleDelay(delay_samples);
29 callback();
30 }
31}
32
33Vruta::SoundRoutine line(Vruta::TaskScheduler& scheduler, float start_value, float end_value, float duration_seconds, uint32_t step_duration, bool restartable)
34{
35 auto& promise_ref = co_await GetAudioPromise {};
36
37 promise_ref.set_state("current_value", start_value);
38 promise_ref.set_state("end_value", end_value);
39 promise_ref.set_state("restart", false);
40
41 const unsigned int sample_rate = scheduler.get_rate();
42 if (step_duration < 1) {
43 step_duration = 1;
44 }
45
46 uint64_t total_samples = (uint64_t)duration_seconds * sample_rate;
47 float per_sample_step = (end_value - start_value) / (float)total_samples;
48 float sample_step = per_sample_step * (float)step_duration;
49
50 promise_ref.set_state("step", sample_step);
51
52 for (;;) {
53 auto current_value = promise_ref.get_state<float>("current_value");
54 auto last_value = promise_ref.get_state<float>("end_value");
55 auto step = promise_ref.get_state<float>("step");
56
57 if (!current_value || !last_value || !step) {
58 MF_ERROR(Journal::Component::Kriya, Journal::Context::CoroutineScheduling, "Line task state not properly initialized");
59 co_return;
60 }
61
62 *current_value = start_value;
63
64 uint64_t samples_elapsed = 0;
65
66 co_await SampleDelay { 1 };
67
68 while (samples_elapsed < total_samples) {
69 *current_value += *step;
70
71 if ((*step > 0 && *current_value >= *last_value) || (*step < 0 && *current_value <= *last_value)) {
72 *current_value = *last_value;
73 }
74
75 samples_elapsed += step_duration;
76 co_await SampleDelay { step_duration };
77 }
78
79 if (!restartable)
80 break;
81
82 auto restart_requested = promise_ref.get_state<bool>("restart");
83 if (restart_requested && *restart_requested) {
84 *restart_requested = false;
85 continue;
86 }
87
88 promise_ref.auto_resume = false;
89 co_await std::suspend_always {};
90 }
91}
92
93Vruta::SoundRoutine pattern(Vruta::TaskScheduler& scheduler, std::function<std::any(uint64_t)> pattern_func, std::function<void(std::any)> callback, double interval_seconds)
94{
95 uint64_t interval_samples = scheduler.seconds_to_samples(interval_seconds);
96 uint64_t step = 0;
97
98 while (true) {
99 std::any value = pattern_func(step++);
100 callback(value);
101 co_await SampleDelay(interval_samples);
102 }
103}
104
106 Vruta::TaskScheduler& scheduler,
107 std::function<void()> callback,
108 std::shared_ptr<Nodes::Generator::Logic> logic_node,
109 bool open)
110{
111 auto& promise_ref = co_await GetAudioPromise {};
112
113 if (!logic_node) {
114 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
115 }
116
117 if (open) {
118 logic_node->while_true([callback](const Nodes::NodeContext& /*ctx*/) {
119 callback();
120 });
121 } else {
122 logic_node->while_false([callback](const Nodes::NodeContext& /*ctx*/) {
123 callback();
124 });
125 }
126
127 while (true) {
128 if (promise_ref.should_terminate) {
129 break;
130 }
131
132 logic_node->process_sample(0.0);
133
134 co_await SampleDelay { 1 };
135 }
136}
137
139 Vruta::TaskScheduler& scheduler,
140 bool target_state,
141 std::function<void()> callback,
142 std::shared_ptr<Nodes::Generator::Logic> logic_node)
143{
144 auto& promise_ref = co_await GetAudioPromise {};
145
146 if (!logic_node) {
147 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
148 }
149
150 logic_node->on_change_to(target_state,
151 [callback](const Nodes::NodeContext& /*ctx*/) {
152 callback();
153 });
154
155 while (true) {
156 if (promise_ref.should_terminate) {
157 break;
158 }
159
160 logic_node->process_sample(0.0);
161
162 co_await SampleDelay { 1 };
163 }
164}
165
167 Vruta::TaskScheduler& scheduler,
168 std::function<void()> callback,
169 std::shared_ptr<Nodes::Generator::Logic> logic_node)
170{
171 auto& promise_ref = co_await GetAudioPromise {};
172
173 if (!logic_node) {
174 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
175 }
176
177 logic_node->on_change([callback](const Nodes::NodeContext& /*ctx*/) {
178 callback();
179 });
180
181 while (true) {
182 if (promise_ref.should_terminate) {
183 break;
184 }
185
186 logic_node->process_sample(0.0);
187
188 co_await SampleDelay { 1 };
189 }
190}
191}
#define MF_ERROR(comp, ctx,...)
Base context class for node callbacks.
Definition Node.hpp:30
A C++20 coroutine-based audio processing task with sample-accurate timing.
Definition Routine.hpp:316
uint64_t seconds_to_samples(double seconds) const
Converts a time in seconds to a number of samples.
unsigned int get_rate(ProcessingToken token=ProcessingToken::SAMPLE_ACCURATE) const
Get processing rate for a domain.
Token-based multimodal task scheduling system for unified coroutine processing.
Definition Scheduler.hpp:51
@ CoroutineScheduling
Coroutine scheduling and temporal coordination (Vruta::TaskScheduler)
@ Kriya
Automatable tasks and fluent scheduling api for Nodes and Buffers.
Vruta::SoundRoutine sequence(Vruta::TaskScheduler &scheduler, std::vector< std::pair< double, std::function< void()> > > sequence)
Creates a temporal sequence that executes callbacks at specified time offsets.
Definition Tasks.cpp:24
Vruta::SoundRoutine Trigger(Vruta::TaskScheduler &scheduler, 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:138
Vruta::SoundRoutine pattern(Vruta::TaskScheduler &scheduler, std::function< std::any(uint64_t)> pattern_func, std::function< void(std::any)> callback, double interval_seconds)
Creates a generative algorithm that produces values based on a pattern function.
Definition Tasks.cpp:93
Vruta::SoundRoutine Toggle(Vruta::TaskScheduler &scheduler, 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:166
Vruta::SoundRoutine line(Vruta::TaskScheduler &scheduler, 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:33
Vruta::SoundRoutine Gate(Vruta::TaskScheduler &scheduler, 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:105
Vruta::SoundRoutine metro(Vruta::TaskScheduler &scheduler, double interval_seconds, std::function< void()> callback)
Creates a periodic event generator that executes a callback at regular intervals.
Definition Tasks.cpp:10
Templated awaitable for accessing a coroutine's promise object.
Awaitable object for precise sample-accurate timing delays.