18 while (!p.should_terminate) {
23 return std::make_shared<Vruta::GraphicsRoutine>(coro(interval_seconds, std::move(callback)));
28 while (!p.should_terminate) {
33 return std::make_shared<Vruta::SoundRoutine>(coro(interval_seconds, std::move(callback)));
40 for (
const auto& [time, cb] : seq) {
45 return std::make_shared<Vruta::GraphicsRoutine>(coro(std::move(
sequence)));
47 auto coro = [](std::vector<std::pair<double, std::function<void()>>> seq) ->
Vruta::SoundRoutine {
48 for (
const auto& [time, cb] : seq) {
53 return std::make_shared<Vruta::SoundRoutine>(coro(std::move(
sequence)));
56Vruta::SoundRoutine line(
float start_value,
float end_value,
float duration_seconds, uint32_t step_duration,
bool restartable)
60 promise_ref.set_state(
"current_value", start_value);
61 promise_ref.set_state(
"end_value", end_value);
62 promise_ref.set_state(
"restart",
false);
65 if (step_duration < 1) {
69 uint64_t total_samples = (uint64_t)duration_seconds * sample_rate;
70 float per_sample_step = (end_value - start_value) / (
float)total_samples;
71 float sample_step = per_sample_step * (float)step_duration;
73 promise_ref.set_state(
"step", sample_step);
76 auto current_value = promise_ref.get_state<
float>(
"current_value");
77 auto last_value = promise_ref.get_state<
float>(
"end_value");
78 auto step = promise_ref.get_state<
float>(
"step");
80 if (!current_value || !last_value || !step) {
85 *current_value = start_value;
87 uint64_t samples_elapsed = 0;
91 while (samples_elapsed < total_samples) {
92 *current_value += *step;
94 if ((*step > 0 && *current_value >= *last_value) || (*step < 0 && *current_value <= *last_value)) {
95 *current_value = *last_value;
98 samples_elapsed += step_duration;
105 auto restart_requested = promise_ref.get_state<
bool>(
"restart");
106 if (restart_requested && *restart_requested) {
107 *restart_requested =
false;
111 promise_ref.auto_resume =
false;
112 co_await std::suspend_always {};
116std::shared_ptr<Vruta::Routine>
pattern(std::function<std::any(uint64_t)> pattern_func, std::function<
void(std::any)> callback,
double interval_seconds,
Vruta::ProcessingToken token)
119 auto coro = [](std::function<std::any(uint64_t)> fn, std::function<void(std::any)> cb,
double interval) ->
Vruta::GraphicsRoutine {
127 return std::make_shared<Vruta::GraphicsRoutine>(coro(std::move(pattern_func), std::move(callback), interval_seconds));
130 auto coro = [](std::function<std::any(uint64_t)> fn, std::function<void(std::any)> cb,
double interval) ->
Vruta::SoundRoutine {
138 return std::make_shared<Vruta::SoundRoutine>(coro(std::move(pattern_func), std::move(callback), interval_seconds));
142 std::function<
void()> callback,
143 std::shared_ptr<Nodes::Generator::Logic> logic_node,
149 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
163 if (promise_ref.should_terminate) {
167 logic_node->process_sample(0.0);
175 std::function<
void()> callback,
176 std::shared_ptr<Nodes::Generator::Logic> logic_node)
181 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
184 logic_node->on_change_to(target_state,
190 if (promise_ref.should_terminate) {
194 logic_node->process_sample(0.0);
201 std::function<
void()> callback,
202 std::shared_ptr<Nodes::Generator::Logic> logic_node)
207 logic_node = std::make_shared<Nodes::Generator::Logic>(0.5);
215 if (promise_ref.should_terminate) {
219 logic_node->process_sample(0.0);
#define MF_ERROR(comp, ctx,...)
Base context class for node callbacks.
A C++20 coroutine-based graphics processing task with frame-accurate timing.
A C++20 coroutine-based audio processing task with sample-accurate timing.
@ 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.
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.
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.
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.
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.
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.
std::shared_ptr< Vruta::Routine > pattern(std::function< std::any(uint64_t)> pattern_func, std::function< void(std::any)> callback, double interval_seconds, Vruta::ProcessingToken token)
Creates a generative algorithm that produces values based on a pattern function.
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.
uint32_t s_registered_sample_rate
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.