aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
committerDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
commitf293da6bc4f0f631c086d35666e3e8bfef19b8f2 (patch)
treed0e693bdec5e4a53daca500434533d2fc5c43650 /src/engine
parentdb319f5a8cb7915b2d5b93adab148fa16d92e7e5 (diff)
downloadmachina-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')
-rw-r--r--src/engine/Action.cpp3
-rw-r--r--src/engine/Action.hpp (renamed from src/engine/machina/Action.hpp)3
-rw-r--r--src/engine/ActionFactory.cpp4
-rw-r--r--src/engine/ActionFactory.hpp (renamed from src/engine/machina/ActionFactory.hpp)0
-rw-r--r--src/engine/Edge.cpp11
-rw-r--r--src/engine/Edge.hpp (renamed from src/engine/machina/Edge.hpp)5
-rw-r--r--src/engine/Engine.cpp86
-rw-r--r--src/engine/JackDriver.cpp20
-rw-r--r--src/engine/JackDriver.hpp3
-rw-r--r--src/engine/LearnRequest.cpp28
-rw-r--r--src/engine/LearnRequest.hpp31
-rw-r--r--src/engine/Loader.cpp12
-rw-r--r--src/engine/Machine.cpp37
-rw-r--r--src/engine/MachineBuilder.cpp6
-rw-r--r--src/engine/MidiAction.cpp6
-rw-r--r--src/engine/MidiAction.hpp (renamed from src/engine/machina/MidiAction.hpp)4
-rw-r--r--src/engine/Mutation.cpp7
-rw-r--r--src/engine/Node.cpp51
-rw-r--r--src/engine/Node.hpp (renamed from src/engine/machina/Node.hpp)15
-rw-r--r--src/engine/Problem.cpp4
-rw-r--r--src/engine/SMFDriver.cpp18
-rw-r--r--src/engine/SMFDriver.hpp (renamed from src/engine/machina/SMFDriver.hpp)2
-rw-r--r--src/engine/Stateful.cpp4
-rw-r--r--src/engine/Stateful.hpp (renamed from src/engine/machina/Stateful.hpp)19
-rw-r--r--src/engine/machina/Driver.hpp11
-rw-r--r--src/engine/machina/Engine.hpp17
-rw-r--r--src/engine/machina/Machine.hpp8
-rw-r--r--src/engine/machina/types.hpp6
-rw-r--r--src/engine/wscript5
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'