diff options
author | David Robillard <d@drobilla.net> | 2011-01-10 21:23:14 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-01-10 21:23:14 +0000 |
commit | f293da6bc4f0f631c086d35666e3e8bfef19b8f2 (patch) | |
tree | d0e693bdec5e4a53daca500434533d2fc5c43650 /src/engine | |
parent | db319f5a8cb7915b2d5b93adab148fa16d92e7e5 (diff) | |
download | machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.gz machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.bz2 machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.zip |
Rewrite with UI/engine split.
Note some things aren't quite working right again yet...
git-svn-id: http://svn.drobilla.net/lad/trunk/machina@2821 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
29 files changed, 280 insertions, 146 deletions
diff --git a/src/engine/Action.cpp b/src/engine/Action.cpp index 14f7158..67a41c2 100644 --- a/src/engine/Action.cpp +++ b/src/engine/Action.cpp @@ -17,7 +17,8 @@ #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Action.hpp" + +#include "Action.hpp" namespace Machina { diff --git a/src/engine/machina/Action.hpp b/src/engine/Action.hpp index 84181a3..ceeea6a 100644 --- a/src/engine/machina/Action.hpp +++ b/src/engine/Action.hpp @@ -25,8 +25,9 @@ #include "raul/SharedPtr.hpp" #include "raul/TimeSlice.hpp" +#include "machina/types.hpp" + #include "Stateful.hpp" -#include "types.hpp" namespace Machina { diff --git a/src/engine/ActionFactory.cpp b/src/engine/ActionFactory.cpp index d486c7d..d5fc954 100644 --- a/src/engine/ActionFactory.cpp +++ b/src/engine/ActionFactory.cpp @@ -15,8 +15,8 @@ * along with Machina. If not, see <http://www.gnu.org/licenses/>. */ -#include "machina/ActionFactory.hpp" -#include "machina/MidiAction.hpp" +#include "ActionFactory.hpp" +#include "MidiAction.hpp" namespace Machina { diff --git a/src/engine/machina/ActionFactory.hpp b/src/engine/ActionFactory.hpp index 04b0c74..04b0c74 100644 --- a/src/engine/machina/ActionFactory.hpp +++ b/src/engine/ActionFactory.hpp diff --git a/src/engine/Edge.cpp b/src/engine/Edge.cpp index 47335fb..8acdca3 100644 --- a/src/engine/Edge.cpp +++ b/src/engine/Edge.cpp @@ -17,13 +17,20 @@ #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" + #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" + +#include "Edge.hpp" +#include "Node.hpp" namespace Machina { +void +Edge::set(URIInt key, const Raul::Atom& value) +{ + std::cout << "EDGE SET " << key << " = " << value << std::endl; +} void Edge::write_state(Redland::Model& model) diff --git a/src/engine/machina/Edge.hpp b/src/engine/Edge.hpp index 8a2d1c2..8e34292 100644 --- a/src/engine/machina/Edge.hpp +++ b/src/engine/Edge.hpp @@ -25,9 +25,10 @@ #include "raul/SharedPtr.hpp" #include "raul/WeakPtr.hpp" +#include "machina/types.hpp" + #include "Action.hpp" #include "Stateful.hpp" -#include "types.hpp" namespace Machina { @@ -35,13 +36,13 @@ class Node; class Edge : public Stateful { public: - Edge(WeakPtr<Node> tail, SharedPtr<Node> head) : _probability(1.0f) , _tail(tail) , _head(head) {} + void set(URIInt key, const Raul::Atom& value); void write_state(Redland::Model& model); WeakPtr<Node> tail() { return _tail; } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 612176a..03762b6 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -21,13 +21,21 @@ #include "machina/Engine.hpp" #include "machina/Loader.hpp" #include "machina/Machine.hpp" -#include "machina/SMFDriver.hpp" +#include "SMFDriver.hpp" #ifdef HAVE_JACK #include "JackDriver.hpp" #endif namespace Machina { +Engine::Engine(SharedPtr<Driver> driver, Redland::World& rdf_world) + : _driver(driver) + , _rdf_world(rdf_world) + , _loader(_rdf_world) +{ +} + + SharedPtr<Driver> Engine::new_driver(const std::string& name, SharedPtr<Machine> machine) { @@ -39,7 +47,7 @@ Engine::new_driver(const std::string& name, SharedPtr<Machine> machine) } #endif if (name == "smf") - return SharedPtr<Driver>(new SMFDriver(machine)); + return SharedPtr<Driver>(new SMFDriver(machine->time().unit())); std::cerr << "Error: Unknown driver type `" << name << "'" << std::endl; return SharedPtr<Driver>(); @@ -51,54 +59,68 @@ Engine::new_driver(const std::string& name, SharedPtr<Machine> machine) SharedPtr<Machine> Engine::load_machine(const Glib::ustring& uri) { - SharedPtr<Machine> old_machine = _driver->machine(); // Hold a reference to current machine.. - - SharedPtr<Machine> m = _loader.load(uri); - if (m) { - m->activate(); - _driver->set_machine(m); + SharedPtr<Machine> machine = _loader.load(uri); + SharedPtr<Machine> old_machine; + if (machine) { + old_machine = _driver->machine(); // Keep a reference to old machine... + machine->activate(); + _driver->set_machine(machine); // Switch driver to new machine } // .. and drop it in this thread (to prevent deallocation in the RT thread) - return m; + return machine; } - -/** Load the machine at @a uri, and insert it into the current machine.. +/** Build a machine from the MIDI at @a uri, and run it (replacing current machine). * Safe to call while engine is processing. */ SharedPtr<Machine> -Engine::import_machine(const Glib::ustring& uri) +Engine::load_machine_midi(const Glib::ustring& uri, double q, Raul::TimeDuration dur) { - SharedPtr<Machine> m = _loader.load(uri); - if (m) { - m->activate(); - _driver->machine()->nodes().append(m->nodes()); + SharedPtr<SMFDriver> file_driver(new SMFDriver(dur.unit())); + SharedPtr<Machine> machine = file_driver->learn(uri, q, dur); + SharedPtr<Machine> old_machine; + if (machine) { + old_machine = _driver->machine(); // Keep a reference to old machine... + machine->activate(); + _driver->set_machine(machine); // Switch driver to new machine } - // Discard m + // .. and drop it in this thread (to prevent deallocation in the RT thread) - return _driver->machine(); + return machine; } - -/** Learn the SMF (MIDI) file at @a uri, add it to the current machine. - * Safe to call while engine is processing. - */ -SharedPtr<Machine> -Engine::import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration duration) +void +Engine::import_machine(SharedPtr<Machine> machine) { - SharedPtr<SMFDriver> file_driver(new SMFDriver()); - SharedPtr<Machine> m = file_driver->learn(uri, q, duration); - m->activate(); - _driver->machine()->nodes().append(m->nodes()); - - // Discard m - - return _driver->machine(); + machine->activate(); + _driver->machine()->nodes().append(machine->nodes()); + // FIXME: thread safe? + // FIXME: announce } +void +Engine::export_midi(const Glib::ustring& filename, Raul::TimeDuration dur) +{ + SharedPtr<Machine> machine = _driver->machine(); + SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver(dur.unit())); + + const bool activated = _driver->is_activated(); + if (activated) + _driver->deactivate(); // FIXME: disable instead + + machine->set_sink(file_driver->writer()); + file_driver->writer()->start(filename, TimeStamp(dur.unit(), 0.0)); + file_driver->run(machine, dur); + machine->set_sink(_driver); + machine->reset(machine->time()); + file_driver->writer()->finish(); + + if (activated) + _driver->activate(); +} void Engine::set_bpm(double bpm) diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index 6f3afe0..ca86111 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -19,10 +19,12 @@ #include <iomanip> #include "machina-config.h" -#include "machina/MidiAction.hpp" +#include "machina/URIs.hpp" +#include "machina/Updates.hpp" #include "JackDriver.hpp" #include "LearnRequest.hpp" +#include "MidiAction.hpp" #include "jack_compat.h" using namespace Raul; @@ -222,6 +224,18 @@ JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time) learn->finish( TimeStamp(TimeUnit::frames(sample_rate()), jack_last_frame_time(_client) + ev.time, 0)); + + const uint64_t id = Stateful::next_id(); + write_set(_updates, id, + URIs::instance().rdf_type, + URIs::instance().machina_MidiAction_atom); + write_set(_updates, learn->node()->id(), + URIs::instance().machina_enter_action, + Raul::Atom((int32_t)id)); + write_set(_updates, id, + URIs::instance().machina_note_number, + Raul::Atom((int32_t)ev.buffer[1])); + machine->clear_pending_learn(); } } @@ -235,7 +249,7 @@ JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time) void JackDriver::write_event(Raul::TimeStamp time, size_t size, - const byte* event) throw (std::logic_error) + const byte* event) { if (!_output_port) return; @@ -327,7 +341,7 @@ JackDriver::on_process(jack_nframes_t nframes) goto end; while (true) { - const uint32_t run_dur_frames = machine->run(_cycle_time); + const uint32_t run_dur_frames = machine->run(_cycle_time, _updates); if (run_dur_frames == 0) { // Machine didn't run at all (machine has no initial states) diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp index 756f717..133c7ed 100644 --- a/src/engine/JackDriver.hpp +++ b/src/engine/JackDriver.hpp @@ -25,7 +25,6 @@ #include "raul/Command.hpp" #include "raul/DoubleBuffer.hpp" -#include "raul/EventRingBuffer.hpp" #include "raul/Semaphore.hpp" #include "raul/SharedPtr.hpp" @@ -61,7 +60,7 @@ public: void write_event(Raul::TimeStamp time, size_t size, - const unsigned char* event) throw (std::logic_error); + const unsigned char* event); void set_bpm(double bpm) { _bpm.set(bpm); } void set_quantization(double q) { _quantization.set(q); } diff --git a/src/engine/LearnRequest.cpp b/src/engine/LearnRequest.cpp index 6643602..b103c65 100644 --- a/src/engine/LearnRequest.cpp +++ b/src/engine/LearnRequest.cpp @@ -21,6 +21,34 @@ namespace Machina { +LearnRequest::LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node) + : _started(false) + , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant + , _quantization(0) // irrelevant + , _node(node) + , _enter_action(new MidiAction(4, NULL)) + , _exit_action(new MidiAction(4, NULL)) +{ + maid->manage(_enter_action); + maid->manage(_exit_action); +} + +SharedPtr<LearnRequest> +LearnRequest::create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node) +{ + SharedPtr<LearnRequest> ret(new LearnRequest(maid, node)); + maid->manage(ret); + return ret; +} + +void +LearnRequest::start(double q, Raul::TimeStamp time) +{ + _started = true; + _start_time = time; + _quantization = q; +} + /** Add the learned actions to the node */ void LearnRequest::finish(TimeStamp time) diff --git a/src/engine/LearnRequest.hpp b/src/engine/LearnRequest.hpp index 7d02564..3de98ea 100644 --- a/src/engine/LearnRequest.hpp +++ b/src/engine/LearnRequest.hpp @@ -21,10 +21,11 @@ #include "raul/Maid.hpp" #include "raul/SharedPtr.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" #include "machina/types.hpp" +#include "MidiAction.hpp" +#include "Node.hpp" + namespace Machina { class Node; @@ -35,38 +36,20 @@ class MidiAction; */ class LearnRequest : public Raul::Deletable { public: - static SharedPtr<LearnRequest> - create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node) - { - SharedPtr<LearnRequest> ret(new LearnRequest(maid, node)); - maid->manage(ret); - return ret; - } - - void start(double q, Raul::TimeStamp time) - { _started = true; _start_time = time; _quantization = q; } + create(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node); + void start(double q, Raul::TimeStamp time); void finish(TimeStamp time); - bool started() { return _started; } + inline bool started() const { return _started; } const SharedPtr<Node>& node() { return _node; } const SharedPtr<MidiAction>& enter_action() { return _enter_action; } const SharedPtr<MidiAction>& exit_action() { return _exit_action; } private: - LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node) - : _started(false) - , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant - , _quantization(0) // irrelevant - , _node(node) - , _enter_action(new MidiAction(4, NULL)) - , _exit_action(new MidiAction(4, NULL)) - { - maid->manage(_enter_action); - maid->manage(_exit_action); - } + LearnRequest(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node); bool _started; TimeStamp _start_time; diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp index 78992d5..2698491 100644 --- a/src/engine/Loader.cpp +++ b/src/engine/Loader.cpp @@ -15,17 +15,21 @@ * along with Machina. If not, see <http://www.gnu.org/licenses/>. */ +#include <cmath> #include <iostream> #include <map> -#include <cmath> + #include <glibmm/ustring.h> + #include "redlandmm/Query.hpp" + #include "machina/Loader.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/ActionFactory.hpp" + #include "machina-config.h" +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "Node.hpp" using namespace Raul; using namespace std; diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index 18ce5de..32ac10d 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -17,20 +17,26 @@ #include <cstdlib> +#include "raul/Atom.hpp" #include "raul/SharedPtr.hpp" #include "redlandmm/Model.hpp" #include "redlandmm/World.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" +#include "machina/Updates.hpp" +#include "machina/URIs.hpp" +#include "Edge.hpp" +#include "Node.hpp" #include "LearnRequest.hpp" +#include "MidiAction.hpp" using namespace std; using namespace Raul; +static const Raul::Atom true_atom(true); +static const Raul::Atom false_atom(false); + namespace Machina { @@ -162,7 +168,7 @@ Machine::remove_node(SharedPtr<Node> node) _nodes.erase(_nodes.find(node)); for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) - (*n)->remove_edges_to(node); + (*n)->remove_edge_to(node); } @@ -217,7 +223,7 @@ Machine::earliest_node() const * Returns true if node was entered, or false if the maximum active nodes has been reached. */ bool -Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) +Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates) { assert(!node->is_active()); @@ -229,6 +235,8 @@ Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) node->enter(sink, _time); assert(node->is_active()); _active_nodes.at(index) = node; + + write_set(updates, node->id(), URIs::instance().machina_active, true_atom); return true; } index = (index + 1) % MAX_ACTIVE_NODES; @@ -243,9 +251,11 @@ Machine::enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) /** Exit an active node at the current _time. */ void -Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) +Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates) { node->exit(sink, _time); + write_set(updates, node->id(), URIs::instance().machina_active, false_atom); + assert(!node->is_active()); for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) @@ -267,7 +277,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) && rand_normal > range_min && rand_normal < range_min + (*s)->probability()) { - enter_node(sink, (*s)->head()); + enter_node(sink, (*s)->head(), updates); break; } else { @@ -286,7 +296,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) SharedPtr<Node> head = (*e)->head(); if ( ! head->is_active()) - enter_node(sink, head); + enter_node(sink, head, updates); } } @@ -304,7 +314,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node) * with sample accuracy if necessary). */ uint32_t -Machine::run(const Raul::TimeSlice& time) +Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates) { if (_is_finished) return 0; @@ -321,11 +331,13 @@ Machine::run(const Raul::TimeSlice& time) bool entered = false; if ( ! _nodes.empty()) { for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { - if ((*n)->is_active()) + if ((*n)->is_active()) { (*n)->exit(sink, _time); + write_set(updates, (*n)->id(), URIs::instance().machina_active, false_atom); + } if ((*n)->is_initial()) { - if (enter_node(sink, (*n))) + if (enter_node(sink, (*n), updates)) entered = true; } } @@ -352,7 +364,7 @@ Machine::run(const Raul::TimeSlice& time) } else if (time.beats_to_ticks(earliest->exit_time()) < cycle_end_frames) { // Earliest active state ends this cycle _time = earliest->exit_time(); - exit_node(sink, earliest); + exit_node(sink, earliest, updates); } else { // Earliest active state ends in the future, done this cycle @@ -376,7 +388,6 @@ Machine::learn(SharedPtr<Raul::Maid> maid, SharedPtr<Node> node) _pending_learn = LearnRequest::create(maid, node); } - void Machine::write_state(Redland::Model& model) { diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp index 629ce57..3bf9152 100644 --- a/src/engine/MachineBuilder.cpp +++ b/src/engine/MachineBuilder.cpp @@ -21,12 +21,12 @@ #include "raul/SharedPtr.hpp" #include "raul/Quantizer.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" +#include "Edge.hpp" +#include "Node.hpp" #include "MachineBuilder.hpp" +#include "MidiAction.hpp" using namespace std; using namespace Raul; diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp index e56202c..819e63b 100644 --- a/src/engine/MidiAction.cpp +++ b/src/engine/MidiAction.cpp @@ -16,11 +16,15 @@ */ #include <iostream> + #include "raul/SharedPtr.hpp" #include "raul/MIDISink.hpp" #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" -#include "machina/MidiAction.hpp" + +#include "machina/types.hpp" + +#include "MidiAction.hpp" namespace Machina { diff --git a/src/engine/machina/MidiAction.hpp b/src/engine/MidiAction.hpp index 73aed7b..f8b3fdc 100644 --- a/src/engine/machina/MidiAction.hpp +++ b/src/engine/MidiAction.hpp @@ -20,7 +20,9 @@ #include "raul/AtomicPtr.hpp" #include "raul/TimeSlice.hpp" -#include "types.hpp" + +#include "machina/types.hpp" + #include "Action.hpp" namespace Raul { class MIDISink; } diff --git a/src/engine/Mutation.cpp b/src/engine/Mutation.cpp index c41b968..55d5715 100644 --- a/src/engine/Mutation.cpp +++ b/src/engine/Mutation.cpp @@ -18,12 +18,13 @@ #include <iostream> #include <cstdlib> -#include "machina/ActionFactory.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" #include "machina/Mutation.hpp" +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "MidiAction.hpp" + using namespace std; namespace Machina { diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp index e150a6f..b7eaf66 100644 --- a/src/engine/Node.cpp +++ b/src/engine/Node.cpp @@ -21,9 +21,12 @@ #include "raul/AtomRDF.hpp" #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" -#include "machina/ActionFactory.hpp" + +#include "machina/URIs.hpp" + +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "Node.hpp" using namespace Raul; using namespace std; @@ -32,24 +35,24 @@ namespace Machina { Node::Node(TimeDuration duration, bool initial) - : _is_initial(initial) + : _enter_time(duration.unit()) + , _duration(duration) + , _is_initial(initial) , _is_selector(false) , _is_active(false) - , _enter_time(duration.unit()) - , _duration(duration) { } Node::Node(const Node& copy) : Stateful() // don't copy RDF ID - , _is_initial(copy._is_initial) - , _is_selector(copy._is_selector) - , _is_active(false) , _enter_time(copy._enter_time) , _duration(copy._duration) , _enter_action(ActionFactory::copy(copy._enter_action)) , _exit_action(ActionFactory::copy(copy._exit_action)) + , _is_initial(copy._is_initial) + , _is_selector(copy._is_selector) + , _is_active(false) { for (Edges::const_iterator i = copy._edges.begin(); i != copy._edges.end(); ++i) { SharedPtr<Edge> edge(new Edge(*i->get())); @@ -187,20 +190,30 @@ Node::connected_to(SharedPtr<Node> node) } -void -Node::remove_edges_to(SharedPtr<Node> node) +SharedPtr<Edge> +Node::remove_edge_to(SharedPtr<Node> node) { - for (Edges::iterator i = _edges.begin(); i != _edges.end() ; ) { - Edges::iterator next = i; - ++next; - - if ((*i)->head() == node) + for (Edges::iterator i = _edges.begin(); i != _edges.end(); ++i) { + if ((*i)->head() == node) { + SharedPtr<Edge> edge(*i); _edges.erase(i); - - i = next; + edges_changed(); + return edge; + } } - edges_changed(); + return SharedPtr<Edge>(); +} + + +void +Node::set(URIInt key, const Raul::Atom& value) +{ + if (key == URIs::instance().machina_initial) { + set_initial(value.get_bool()); + } else if (key == URIs::instance().machina_selector) { + set_selector(value.get_bool()); + } } diff --git a/src/engine/machina/Node.hpp b/src/engine/Node.hpp index 57f62f1..13f6bb3 100644 --- a/src/engine/machina/Node.hpp +++ b/src/engine/Node.hpp @@ -44,8 +44,6 @@ using Raul::TimeUnit; */ class Node : public Stateful { public: - typedef std::string ID; - Node(TimeDuration duration, bool initial=false); Node(const Node& copy); @@ -62,9 +60,10 @@ public: void add_edge(SharedPtr<Edge> edge); void remove_edge(SharedPtr<Edge> edge); - void remove_edges_to(SharedPtr<Node> node); + SharedPtr<Edge> remove_edge_to(SharedPtr<Node> node); bool connected_to(SharedPtr<Node> node); + void set(URIInt key, const Raul::Atom& value); void write_state(Redland::Model& model); bool is_initial() const { return _is_initial; } @@ -72,7 +71,7 @@ public: bool is_active() const { return _is_active; } TimeStamp enter_time() const { assert(_is_active); return _enter_time; } TimeStamp exit_time() const { assert(_is_active); return _enter_time + _duration; } - TimeDuration duration() { return _duration; } + TimeDuration duration() const { return _duration; } void set_duration(TimeDuration d) { _duration = d; } bool is_selector() const { return _is_selector; } void set_selector(bool i); @@ -88,15 +87,15 @@ public: private: Node& operator=(const Node& other); // undefined - Schrodinbit _changed; - bool _is_initial; - bool _is_selector; - bool _is_active; TimeStamp _enter_time; ///< valid iff _is_active TimeDuration _duration; SharedPtr<Action> _enter_action; SharedPtr<Action> _exit_action; Edges _edges; + Schrodinbit _changed; + bool _is_initial; + bool _is_selector; + bool _is_active; }; diff --git a/src/engine/Problem.cpp b/src/engine/Problem.cpp index ecd1c6b..bc32667 100644 --- a/src/engine/Problem.cpp +++ b/src/engine/Problem.cpp @@ -23,13 +23,15 @@ #include <iostream> #include "eugene/Problem.hpp" -#include "machina/ActionFactory.hpp" + #include "machina/Edge.hpp" #include "machina/Machine.hpp" + #include "raul/SMFReader.hpp" #include "raul/midi_events.h" #include "machina-config.h" +#include "ActionFactory.hpp" #include "Problem.hpp" using namespace std; diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp index b41ae49..3bf49c5 100644 --- a/src/engine/SMFDriver.cpp +++ b/src/engine/SMFDriver.cpp @@ -15,26 +15,30 @@ * along with Machina. If not, see <http://www.gnu.org/licenses/>. */ -#include <list> #include <iostream> +#include <list> + #include <glibmm/convert.h> + #include "raul/Quantizer.hpp" #include "raul/SharedPtr.hpp" #include "raul/SMFWriter.hpp" #include "raul/SMFReader.hpp" + #include "machina/Machine.hpp" -#include "machina/Edge.hpp" -#include "machina/SMFDriver.hpp" + +#include "Edge.hpp" +#include "SMFDriver.hpp" using namespace std; namespace Machina { -SMFDriver::SMFDriver(SharedPtr<Machine> machine) - : Driver(machine) +SMFDriver::SMFDriver(Raul::TimeUnit unit) + : Driver(SharedPtr<Machine>()) { - _writer = SharedPtr<Raul::SMFWriter>(new Raul::SMFWriter(machine->time().unit())); + _writer = SharedPtr<Raul::SMFWriter>(new Raul::SMFWriter(unit)); } @@ -144,7 +148,7 @@ SMFDriver::run(SharedPtr<Machine> machine, Raul::TimeStamp max_time) Raul::TimeSlice time(machine->time().unit().ppt(), _writer->unit().ppt(), 120.0); time.set_slice(TimeStamp(max_time.unit(), 0, 0), time.beats_to_ticks(max_time)); machine->set_sink(shared_from_this()); - machine->run(time); + machine->run(time, SharedPtr<UpdateBuffer>()); } diff --git a/src/engine/machina/SMFDriver.hpp b/src/engine/SMFDriver.hpp index a10442d..7081dc2 100644 --- a/src/engine/machina/SMFDriver.hpp +++ b/src/engine/SMFDriver.hpp @@ -39,7 +39,7 @@ class Machine; class SMFDriver : public Driver, public boost::enable_shared_from_this<SMFDriver> { public: - SMFDriver(SharedPtr<Machine> machine = SharedPtr<Machine>()); + SMFDriver(Raul::TimeUnit unit); SharedPtr<Machine> learn(const std::string& filename, double q, diff --git a/src/engine/Stateful.cpp b/src/engine/Stateful.cpp index 0e1e3ad..75a1158 100644 --- a/src/engine/Stateful.cpp +++ b/src/engine/Stateful.cpp @@ -15,14 +15,14 @@ * along with Machina. If not, see <http://www.gnu.org/licenses/>. */ -#include "machina/Stateful.hpp" +#include "Stateful.hpp" namespace Machina { uint64_t Stateful::_next_id = 1; Stateful::Stateful() - : _id(_next_id++) + : _id(next_id()) { } diff --git a/src/engine/machina/Stateful.hpp b/src/engine/Stateful.hpp index f35c00a..08a1425 100644 --- a/src/engine/machina/Stateful.hpp +++ b/src/engine/Stateful.hpp @@ -23,19 +23,31 @@ #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" +#include "machina/types.hpp" + +namespace Raul { class Atom; } + namespace Machina { +class URIs; + class Stateful { public: Stateful(); virtual ~Stateful() {} + virtual void set(URIInt key, const Raul::Atom& value) {} virtual void write_state(Redland::Model& model) = 0; uint64_t id() const { return _id; } const Redland::Node& rdf_id(Redland::World& world) const; + static uint64_t next_id() { return _next_id++; } + +protected: + Stateful(uint64_t id) : _id(id) {} + private: static uint64_t _next_id; @@ -43,6 +55,13 @@ private: mutable Redland::Node _rdf_id; }; +class StatefulKey : public Stateful { +public: + StatefulKey(uint64_t id) : Stateful(id) {} + + void write_state(Redland::Model& model) {} +}; + } // namespace Machina #endif // MACHINA_STATEFUL_HPP diff --git a/src/engine/machina/Driver.hpp b/src/engine/machina/Driver.hpp index f850d3d..814f041 100644 --- a/src/engine/machina/Driver.hpp +++ b/src/engine/machina/Driver.hpp @@ -19,12 +19,14 @@ #define MACHINA_DRIVER_HPP #include "raul/MIDISink.hpp" +#include "raul/RingBuffer.hpp" + +#include "machina/types.hpp" namespace Machina { class Machine; - class Driver : public Raul::MIDISink { public: Driver(SharedPtr<Machine> machine) : _machine(machine) {} @@ -33,9 +35,13 @@ public: SharedPtr<Machine> machine() { return _machine; } virtual void set_machine(SharedPtr<Machine> machine) { _machine = machine; } + SharedPtr<UpdateBuffer> update_sink() { return _updates; } + void set_update_sink(SharedPtr<UpdateBuffer> b) { _updates = b; } + virtual void set_bpm(double bpm) = 0; virtual void set_quantization(double q) = 0; + virtual bool is_activated() const { return false; } virtual void activate() {} virtual void deactivate() {} @@ -46,7 +52,8 @@ public: virtual void finish_record() {} protected: - SharedPtr<Machine> _machine; + SharedPtr<Machine> _machine; + SharedPtr<UpdateBuffer> _updates; }; diff --git a/src/engine/machina/Engine.hpp b/src/engine/machina/Engine.hpp index 17d555d..022a2ca 100644 --- a/src/engine/machina/Engine.hpp +++ b/src/engine/machina/Engine.hpp @@ -34,12 +34,7 @@ class Machine; class Engine { public: - Engine(SharedPtr<Driver> driver, Redland::World& rdf_world) - : _driver(driver) - , _rdf_world(rdf_world) - , _loader(_rdf_world) - { - } + Engine(SharedPtr<Driver> driver, Redland::World& rdf_world); Redland::World& rdf_world() { return _rdf_world; } @@ -50,8 +45,14 @@ public: SharedPtr<Machine> machine() { return _driver->machine(); } SharedPtr<Machine> load_machine(const Glib::ustring& uri); - SharedPtr<Machine> import_machine(const Glib::ustring& uri); - SharedPtr<Machine> import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration d); + SharedPtr<Machine> load_machine_midi(const Glib::ustring& uri, + double q, + Raul::TimeDuration dur); + + void import_machine(SharedPtr<Machine> machine); + + void export_midi(const Glib::ustring& filename, + Raul::TimeDuration dur); void set_bpm(double bpm); void set_quantization(double beat_fraction); diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp index e1a0f25..f3469c7 100644 --- a/src/engine/machina/Machine.hpp +++ b/src/engine/machina/Machine.hpp @@ -23,6 +23,7 @@ #include "raul/List.hpp" #include "raul/Maid.hpp" +#include "raul/RingBuffer.hpp" #include "raul/SharedPtr.hpp" #include "raul/TimeSlice.hpp" #include "raul/WeakPtr.hpp" @@ -33,6 +34,7 @@ namespace Machina { +class Controller; class LearnRequest; /** A (Finite State) Machine. @@ -63,7 +65,7 @@ public: // Audio context void reset(Raul::TimeStamp time); - uint32_t run(const Raul::TimeSlice& time); + uint32_t run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates); // Any context inline Raul::TimeStamp time() const { return _time; } @@ -84,8 +86,8 @@ private: // Audio context SharedPtr<Node> earliest_node() const; - bool enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node); - void exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node>); + bool enter_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates); + void exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node>, SharedPtr<UpdateBuffer> updates); static const size_t MAX_ACTIVE_NODES = 128; std::vector< SharedPtr<Node> > _active_nodes; diff --git a/src/engine/machina/types.hpp b/src/engine/machina/types.hpp index c39b682..74410d9 100644 --- a/src/engine/machina/types.hpp +++ b/src/engine/machina/types.hpp @@ -18,10 +18,16 @@ #ifndef MACHINA_TYPES_HPP #define MACHINA_TYPES_HPP +#include "raul/RingBuffer.hpp" + namespace Machina { typedef unsigned char byte; +typedef Raul::RingBuffer UpdateBuffer; + +typedef uint32_t URIInt; + } // namespace Machina #endif // MACHINA_TYPES_HPP diff --git a/src/engine/wscript b/src/engine/wscript index 35f1303..1566a72 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -5,6 +5,7 @@ def build(bld): core_source = ''' Action.cpp ActionFactory.cpp + Controller.cpp Edge.cpp Engine.cpp JackDriver.cpp @@ -18,6 +19,8 @@ def build(bld): Recorder.cpp SMFDriver.cpp Stateful.cpp + Updates.cpp + URIs.cpp ''' if bld.env['HAVE_EUGENE']: core_source += ''' @@ -27,7 +30,7 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = core_source obj.export_includes = ['.'] - obj.includes = ['.', '../..'] + obj.includes = ['.', '..', '../..'] obj.name = 'libmachina_engine' obj.target = 'machina_engine' core_libs = 'GLIBMM GTHREAD RAUL REDLANDMM JACK' |