Implemented start synchronization
This commit is contained in:
parent
99f89c2e8b
commit
8d86dde405
@ -1583,6 +1583,18 @@ static Result<Value> builtin_call(Interpreter &i, std::vector<Value> args)
|
||||
return callable(i, std::move(args));
|
||||
}
|
||||
|
||||
static Result<Value> builtin_start(Interpreter &interpreter, std::span<Ast> args)
|
||||
{
|
||||
interpreter.starter.start();
|
||||
auto result = algo::fold(args, Value{}, [&interpreter](auto const&, Ast const& ast)
|
||||
-> Result<Value>
|
||||
{
|
||||
return Try(interpreter.eval((Ast)ast));
|
||||
});
|
||||
interpreter.starter.stop();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Interpreter::register_builtin_functions()
|
||||
{
|
||||
auto &global = *Env::global;
|
||||
@ -1627,6 +1639,7 @@ void Interpreter::register_builtin_functions()
|
||||
global.force_define("shuffle", builtin_shuffle);
|
||||
global.force_define("sim", builtin_sim);
|
||||
global.force_define("sort", builtin_sort);
|
||||
global.force_define("start", builtin_start);
|
||||
global.force_define("try", builtin_try);
|
||||
global.force_define("typeof", builtin_typeof);
|
||||
global.force_define("uniq", builtin_uniq);
|
||||
|
@ -1,8 +1,9 @@
|
||||
#ifndef MUSIQUE_INTERPRETER_HH
|
||||
#define MUSIQUE_INTERPRETER_HH
|
||||
|
||||
#include <musique/midi/midi.hh>
|
||||
#include <musique/interpreter/context.hh>
|
||||
#include <musique/interpreter/starter.hh>
|
||||
#include <musique/midi/midi.hh>
|
||||
#include <musique/value/value.hh>
|
||||
#include <unordered_map>
|
||||
|
||||
@ -25,6 +26,8 @@ struct Interpreter
|
||||
|
||||
std::function<std::optional<Error>(Interpreter&, Value)> default_action;
|
||||
|
||||
Starter starter;
|
||||
|
||||
Interpreter();
|
||||
~Interpreter();
|
||||
Interpreter(Interpreter &&) = delete;
|
||||
|
81
musique/interpreter/starter.cc
Normal file
81
musique/interpreter/starter.cc
Normal file
@ -0,0 +1,81 @@
|
||||
#include <musique/interpreter/starter.hh>
|
||||
#include <ableton/Link.hpp>
|
||||
#include <musique/errors.hh>
|
||||
|
||||
struct Starter::Implementation
|
||||
{
|
||||
ableton::Link link = {30};
|
||||
|
||||
Implementation()
|
||||
{
|
||||
link.enable(true);
|
||||
link.enableStartStopSync(true);
|
||||
}
|
||||
};
|
||||
|
||||
Starter::Starter()
|
||||
: impl{std::make_shared<Starter::Implementation>()}
|
||||
{
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
ableton::Link *link;
|
||||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
};
|
||||
|
||||
void Starter::start()
|
||||
{
|
||||
ensure(impl != nullptr, "Starter wasn't initialized properly");
|
||||
auto &link = impl->link;
|
||||
|
||||
auto const quantum = 4;
|
||||
|
||||
auto const sessionState = link.captureAppSessionState();
|
||||
|
||||
// If we already started continue
|
||||
if (sessionState.isPlaying()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto state = std::make_shared<State>();
|
||||
state->link = &link;
|
||||
|
||||
link.setStartStopCallback([state = state](bool is_playing)
|
||||
{
|
||||
if (is_playing) {
|
||||
state->condition.notify_all();
|
||||
}
|
||||
});
|
||||
|
||||
std::jthread starter([quantum = quantum, state = state](std::stop_token token)
|
||||
{
|
||||
auto counter = 0;
|
||||
while (!token.stop_requested()) {
|
||||
auto const time = state->link->clock().micros();
|
||||
auto sessionState = state->link->captureAppSessionState();
|
||||
if (counter == 2) {
|
||||
sessionState.setIsPlaying(true, time);
|
||||
state->link->commitAppSessionState(sessionState);
|
||||
return;
|
||||
}
|
||||
auto const phase = sessionState.phaseAtTime(time, quantum);
|
||||
counter += phase == 0;
|
||||
}
|
||||
});
|
||||
|
||||
std::unique_lock lock(state->mutex);
|
||||
state->condition.wait(lock);
|
||||
}
|
||||
|
||||
void Starter::stop()
|
||||
{
|
||||
ensure(impl != nullptr, "Starter wasn't initialized properly");
|
||||
auto &link = impl->link;
|
||||
|
||||
auto const time = link.clock().micros();
|
||||
auto sessionState = link.captureAppSessionState();
|
||||
sessionState.setIsPlaying(false, time);
|
||||
link.commitAppSessionState(sessionState);
|
||||
}
|
17
musique/interpreter/starter.hh
Normal file
17
musique/interpreter/starter.hh
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef MUSIQUE_STARTER_HH
|
||||
#define MUSIQUE_STARTER_HH
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct Starter
|
||||
{
|
||||
Starter();
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
struct Implementation;
|
||||
std::shared_ptr<Implementation> impl;
|
||||
};
|
||||
|
||||
|
||||
#endif // MUSIQUE_STARTER_HH
|
Loading…
Reference in New Issue
Block a user