MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Tasks.cpp
Go to the documentation of this file.
1#include "Tasks.hpp"
2#include "Awaiters.hpp"
5
6namespace MayaFlux::Kriya {
7
8Vruta::SoundRoutine metro(Vruta::TaskScheduler& scheduler, double interval_seconds, std::function<void()> callback)
9{
10 uint64_t interval_samples = scheduler.seconds_to_samples(interval_seconds);
11 auto& promise = co_await Kriya::GetAudioPromise {};
12
13 while (true) {
14 if (promise.should_terminate) {
15 break;
16 }
17 callback();
18 co_await SampleDelay(interval_samples);
19 }
20}
21
22Vruta::SoundRoutine sequence(Vruta::TaskScheduler& scheduler, std::vector<std::pair<double, std::function<void()>>> sequence)
23{
24 for (const auto& [time, callback] : sequence) {
25 uint64_t delay_samples = scheduler.seconds_to_samples(time);
26 co_await SampleDelay(delay_samples);
27 callback();
28 }
29}
30
31Vruta::SoundRoutine line(Vruta::TaskScheduler& scheduler, float start_value, float end_value, float duration_seconds, uint32_t step_duration, bool restartable)
32{
33 auto& promise_ref = co_await GetAudioPromise {};
34
35 promise_ref.set_state("current_value", start_value);
36 promise_ref.set_state("end_value", end_value);
37 promise_ref.set_state("restart", false);
38
39 const unsigned int sample_rate = scheduler.get_rate();
40 if (step_duration < 1) {
41 step_duration = 1;
42 }
43
44 uint64_t total_samples = duration_seconds * sample_rate;
45 float per_sample_step = (end_value - start_value) / total_samples;
46 float sample_step = per_sample_step * step_duration;
47
48 promise_ref.set_state("step", sample_step);
49
50 for (;;) {
51 float* current_value = promise_ref.get_state<float>("current_value");
52 float* last_value = promise_ref.get_state<float>("end_value");
53 float* step = promise_ref.get_state<float>("step");
54
55 if (!current_value || !last_value || !step) {
56 std::cerr << "Error: line task state not properly initialized" << std::endl;
57 co_return;
58 }
59
60 *current_value = start_value;
61
62 uint64_t samples_elapsed = 0;
63
64 co_await SampleDelay { 1 };
65
66 while (samples_elapsed < total_samples) {
67 *current_value += *step;
68
69 if ((*step > 0 && *current_value >= *last_value) || (*step < 0 && *current_value <= *last_value)) {
70 *current_value = *last_value;
71 }
72
73 samples_elapsed += step_duration;
74 co_await SampleDelay { step_duration };
75 }
76
77 if (!restartable)
78 break;
79
80 bool* restart_requested = promise_ref.get_state<bool>("restart");
81 if (restart_requested && *restart_requested) {
82 *restart_requested = false;
83 continue;
84 }
85
86 promise_ref.auto_resume = false;
87 co_await std::suspend_always {};
88 }
89}
90
91Vruta::SoundRoutine pattern(Vruta::TaskScheduler& scheduler, std::function<std::any(uint64_t)> pattern_func, std::function<void(std::any)> callback, double interval_seconds)
92{
93 uint64_t interval_samples = scheduler.seconds_to_samples(interval_seconds);
94 uint64_t step = 0;
95
96 while (true) {
97 std::any value = pattern_func(step++);
98 callback(value);
99 co_await SampleDelay(interval_samples);
100 }
101}
102
104 Vruta::TaskScheduler& scheduler,
105 std::function<void()> callback,
106 std::shared_ptr<Nodes::Generator::Logic> logic_node,
107 bool open)
108{
109 auto& promise_ref = co_await GetAudioPromise {};
110
111 if (!logic_node) {
112 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
113 }
114
115 if (open) {
116 logic_node->while_true([callback](const Nodes::NodeContext& ctx) {
117 callback();
118 });
119 } else {
120 logic_node->while_false([callback](const Nodes::NodeContext& ctx) {
121 callback();
122 });
123 }
124
125 while (true) {
126 if (promise_ref.should_terminate) {
127 break;
128 }
129
130 logic_node->process_sample(0.0);
131
132 co_await SampleDelay { 1 };
133 }
134}
135
137 Vruta::TaskScheduler& scheduler,
138 bool target_state,
139 std::function<void()> callback,
140 std::shared_ptr<Nodes::Generator::Logic> logic_node)
141{
142 auto& promise_ref = co_await GetAudioPromise {};
143
144 if (!logic_node) {
145 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
146 }
147
148 logic_node->on_change_to([callback](const Nodes::NodeContext& ctx) {
149 callback();
150 },
151 target_state);
152
153 while (true) {
154 if (promise_ref.should_terminate) {
155 break;
156 }
157
158 logic_node->process_sample(0.0);
159
160 co_await SampleDelay { 1 };
161 }
162}
163
165 Vruta::TaskScheduler& scheduler,
166 std::function<void()> callback,
167 std::shared_ptr<Nodes::Generator::Logic> logic_node)
168{
169 auto& promise_ref = co_await GetAudioPromise {};
170
171 if (!logic_node) {
172 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
173 }
174
175 logic_node->on_change([callback](const Nodes::NodeContext& ctx) {
176 callback();
177 });
178
179 while (true) {
180 if (promise_ref.should_terminate) {
181 break;
182 }
183
184 logic_node->process_sample(0.0);
185
186 co_await SampleDelay { 1 };
187 }
188}
189}
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:309
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
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:22
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:136
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:91
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:164
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:31
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:103
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:8
Templated awaitable for accessing a coroutine's promise object.
Definition Awaiters.hpp:188
Awaitable object for precise sample-accurate timing delays.
Definition Awaiters.hpp:35