aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-03-30 22:32:07 +0000
committerDavid Robillard <d@drobilla.net>2007-03-30 22:32:07 +0000
commitdd6be02a7478225f19f02432919b64b96b733172 (patch)
tree35d3476f6728801ed1e6b8d124fc85d549e91bfd
parent2124952b855e093d6253bfd763cd9ebfe69e9def (diff)
downloadmachina-dd6be02a7478225f19f02432919b64b96b733172.tar.gz
machina-dd6be02a7478225f19f02432919b64b96b733172.tar.bz2
machina-dd6be02a7478225f19f02432919b64b96b733172.zip
Canvas auto-layout uses durations like graphviz diagrams.
Learning fixes. Added duration spinbutton to MIDI Import dialog. git-svn-id: http://svn.drobilla.net/lad/machina@381 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/Edge.cpp12
-rw-r--r--src/engine/JackDriver.cpp7
-rw-r--r--src/engine/Machine.cpp19
-rw-r--r--src/engine/Node.cpp4
-rw-r--r--src/engine/SMFDriver.cpp13
-rw-r--r--src/engine/machina/Edge.hpp18
-rw-r--r--src/gui/EdgeView.cpp7
-rw-r--r--src/gui/EdgeView.hpp2
-rw-r--r--src/gui/MachinaCanvas.cpp22
-rw-r--r--src/gui/MachinaGUI.cpp18
10 files changed, 72 insertions, 50 deletions
diff --git a/src/engine/Edge.cpp b/src/engine/Edge.cpp
index 1a7d236..f982cda 100644
--- a/src/engine/Edge.cpp
+++ b/src/engine/Edge.cpp
@@ -34,21 +34,21 @@ Edge::write_state(Raul::RDFWriter& writer)
RdfId(RdfId::RESOURCE, "rdf:type"),
RdfId(RdfId::RESOURCE, "machina:Edge"));
- SharedPtr<Node> src = _src.lock();
- SharedPtr<Node> dst = _dst;
+ SharedPtr<Node> tail = _tail.lock();
+ SharedPtr<Node> head = _head;
- if (!src || !dst)
+ if (!tail || !head)
return;
- assert(src->id() && dst->id());
+ assert(tail->id() && head->id());
writer.write(_id,
RdfId(RdfId::RESOURCE, "machina:tail"),
- src->id());
+ tail->id());
writer.write(_id,
RdfId(RdfId::RESOURCE, "machina:head"),
- dst->id());
+ head->id());
writer.write(_id,
RdfId(RdfId::RESOURCE, "machina:probability"),
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index d389e2a..606a8ff 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -182,12 +182,9 @@ JackDriver::write_event(Raul::BeatTime time,
void
JackDriver::on_process(jack_nframes_t nframes)
{
- //using namespace std;
- //std::cerr << "> ======================================================\n";
-
_cycle_time.set_bpm(_bpm.get());
- // (start time set at end of previous cycle)
+ // (N.B. start time set at end of previous cycle)
_cycle_time.set_offset(0);
_cycle_time.set_length(nframes);
@@ -256,8 +253,6 @@ JackDriver::on_process(jack_nframes_t nframes)
/* Remember the last machine run, in case a switch happens and
* we need to finalize it next cycle. */
_last_machine = machine;
-
- //std::cerr << "< ======================================================\n";
}
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index 600dd3d..43fd280 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -56,6 +56,7 @@ void
Machine::add_node(SharedPtr<Node> node)
{
//cerr << "ADDING NODE " << node.get() << endl;
+ assert(_nodes.find(node) == _nodes.end());
_nodes.push_back(node);
}
@@ -78,6 +79,8 @@ Machine::reset()
if (node->is_active())
node->exit(_sink.lock(), _time);
+
+ assert(! node->is_active());
}
}
@@ -150,6 +153,7 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
{
node->exit(sink, _time);
assert(!node->is_active());
+
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
if (_active_nodes[i] == node) {
_active_nodes[i].reset();
@@ -161,13 +165,15 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
for (Node::Edges::const_iterator s = node->outgoing_edges().begin();
s != node->outgoing_edges().end(); ++s) {
+ assert((*s)->head() != node); // no loops
+
const double rand_normal = rand() / (double)RAND_MAX; // [0, 1]
if (rand_normal <= (*s)->probability()) {
- SharedPtr<Node> dst = (*s)->dst();
+ SharedPtr<Node> head = (*s)->head();
- if (!dst->is_active())
- enter_node(sink, dst);
+ if (!head->is_active())
+ enter_node(sink, head);
}
}
}
@@ -187,7 +193,6 @@ Machine::run(const Raul::TimeSlice& time)
{
using namespace std;
if (_is_finished) {
- cerr << "FINISHED\n";
return 0;
}
@@ -195,8 +200,6 @@ Machine::run(const Raul::TimeSlice& time)
const BeatCount cycle_end = _time + time.length_beats();
- //std::cerr << "Start: " << _time << std::endl;
-
assert(_is_activated);
// Initial run, enter all initial states
@@ -249,8 +252,6 @@ Machine::run(const Raul::TimeSlice& time)
}
- //std::cerr << "Done: " << this_time << std::endl;
-
assert(this_time <= time.length_beats());
return this_time;
}
@@ -263,7 +264,7 @@ Machine::run(const Raul::TimeSlice& time)
void
Machine::learn(SharedPtr<LearnRequest> learn)
{
- std::cerr << "LEARN\n";
+ std::cerr << "Learn" << std::endl;
/*LearnRequest request(node,
SharedPtr<MidiAction>(new MidiAction(4, NULL)),
diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp
index 768422e..e51e33d 100644
--- a/src/engine/Node.cpp
+++ b/src/engine/Node.cpp
@@ -92,7 +92,7 @@ Node::exit(SharedPtr<Raul::MIDISink> sink, BeatTime time)
void
Node::add_outgoing_edge(SharedPtr<Edge> edge)
{
- assert(edge->src().lock().get() == this);
+ assert(edge->tail().lock().get() == this);
_outgoing_edges.push_back(edge);
}
@@ -112,7 +112,7 @@ Node::remove_outgoing_edges_to(SharedPtr<Node> node)
Edges::iterator next = i;
++next;
- if ((*i)->dst() == node)
+ if ((*i)->head() == node)
_outgoing_edges.erase(i);
i = next;
diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp
index 33fc686..5b6d940 100644
--- a/src/engine/SMFDriver.cpp
+++ b/src/engine/SMFDriver.cpp
@@ -63,6 +63,8 @@ SMFDriver::learn(const string& filename, unsigned track, double q, Raul::BeatTim
else
learn_track(m, reader, track, q, max_duration);
+ m->reset();
+
if (m->nodes().size() > 1)
return m;
else
@@ -89,6 +91,8 @@ SMFDriver::learn(const string& filename, double q, Raul::BeatTime max_duration)
learn_track(m, reader, t, q, max_duration);
}
+ m->reset();
+
if (m->nodes().size() > 1)
return m;
else
@@ -246,7 +250,7 @@ SMFDriver::learn_track(SharedPtr<Machine> m,
// (these happen after polyphonic sections)
if (is_delay_node(connect_node) && connect_node->duration() == 0
&& connect_node->outgoing_edges().size() == 1
- && (*connect_node->outgoing_edges().begin())->dst() == resolved) {
+ && (*connect_node->outgoing_edges().begin())->head() == resolved) {
connect_node->outgoing_edges().clear();
assert(connect_node->outgoing_edges().empty());
connect_node->set_enter_action(resolved->enter_action());
@@ -301,11 +305,8 @@ SMFDriver::learn_track(SharedPtr<Machine> m,
active_nodes.clear();
}
- if (added_nodes > 0)
- /*if (initial_node->outgoing_edges().size() == 1)
- (*initial_node->outgoing_edges().begin())->dst()->set_initial(true);
- else*/
- m->add_node(initial_node);
+ if (m->nodes().find(initial_node) == m->nodes().end())
+ m->add_node(initial_node);
}
diff --git a/src/engine/machina/Edge.hpp b/src/engine/machina/Edge.hpp
index 7f14788..e8e4ec0 100644
--- a/src/engine/machina/Edge.hpp
+++ b/src/engine/machina/Edge.hpp
@@ -34,19 +34,19 @@ class Node;
class Edge : public Raul::Stateful, public boost::noncopyable {
public:
- Edge(WeakPtr<Node> src, SharedPtr<Node> dst)
+ Edge(WeakPtr<Node> tail, SharedPtr<Node> head)
: _probability(1.0f)
- , _src(src)
- , _dst(dst)
+ , _tail(tail)
+ , _head(head)
{}
void write_state(Raul::RDFWriter& writer);
- WeakPtr<Node> src() { return _src; }
- SharedPtr<Node> dst() { return _dst; }
+ WeakPtr<Node> tail() { return _tail; }
+ SharedPtr<Node> head() { return _head; }
- void set_src(WeakPtr<Node> src) { _src = src; }
- void set_dst(SharedPtr<Node> dst) { _dst = dst; }
+ void set_tail(WeakPtr<Node> tail) { _tail = tail; }
+ void set_head(SharedPtr<Node> head) { _head = head; }
inline float probability() { return _probability.get(); }
inline void set_probability(float p) { _probability.set(p); }
@@ -54,8 +54,8 @@ public:
private:
Raul::DoubleBuffer<float> _probability;
- WeakPtr<Node> _src;
- SharedPtr<Node> _dst;
+ WeakPtr<Node> _tail;
+ SharedPtr<Node> _head;
};
diff --git a/src/gui/EdgeView.cpp b/src/gui/EdgeView.cpp
index 4817eca..fccf8d5 100644
--- a/src/gui/EdgeView.cpp
+++ b/src/gui/EdgeView.cpp
@@ -33,6 +33,13 @@ EdgeView::EdgeView(SharedPtr<FlowCanvas> canvas,
{
}
+
+double
+EdgeView::length_hint() const
+{
+ return _edge->tail().lock()->duration() * 10;
+}
+
void
EdgeView::update_label()
diff --git a/src/gui/EdgeView.hpp b/src/gui/EdgeView.hpp
index c61d0cf..c394d49 100644
--- a/src/gui/EdgeView.hpp
+++ b/src/gui/EdgeView.hpp
@@ -34,6 +34,8 @@ public:
SharedPtr<Machina::Edge> edge() { return _edge; }
void update_label();
+
+ virtual double length_hint() const;
private:
bool on_event(GdkEvent* ev);
diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp
index a6a565e..134b885 100644
--- a/src/gui/MachinaCanvas.cpp
+++ b/src/gui/MachinaCanvas.cpp
@@ -115,25 +115,25 @@ MachinaCanvas::canvas_event(GdkEvent* event)
void
MachinaCanvas::connect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> dst)
+ boost::shared_ptr<NodeView> head)
{
- SharedPtr<Machina::Edge> edge(new Machina::Edge(src->node(), dst->node()));
+ SharedPtr<Machina::Edge> edge(new Machina::Edge(src->node(), head->node()));
src->node()->add_outgoing_edge(edge);
boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- src, dst, edge));
+ src, head, edge));
src->add_connection(c);
- dst->add_connection(c);
+ head->add_connection(c);
add_connection(c);
}
void
MachinaCanvas::disconnect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> dst)
+ boost::shared_ptr<NodeView> head)
{
- src->node()->remove_outgoing_edges_to(dst->node());
- remove_connection(src, dst);
+ src->node()->remove_outgoing_edges_to(head->node());
+ remove_connection(src, head);
#if 0
boost::shared_ptr<MachinaPort> input
@@ -213,16 +213,16 @@ MachinaCanvas::build(SharedPtr<Machina::Machine> machine)
for (Machina::Node::Edges::const_iterator e = view->node()->outgoing_edges().begin();
e != view->node()->outgoing_edges().end(); ++e) {
- SharedPtr<NodeView> dst_view = views[(*e)->dst()];
- if (!dst_view) {
+ SharedPtr<NodeView> head_view = views[(*e)->head()];
+ if (!head_view) {
cerr << "WARNING: Edge to node with no view" << endl;
continue;
}
boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- view, dst_view, (*e)));
+ view, head_view, (*e)));
view->add_connection(c);
- dst_view->add_connection(c);
+ head_view->add_connection(c);
add_connection(c);
}
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index ffbfb5a..de432aa 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -18,6 +18,7 @@
#include <cmath>
#include <sstream>
#include <fstream>
+#include <limits.h>
#include <pthread.h>
#include <libgnomecanvasmm.h>
#include <libglademm/xml.h>
@@ -426,6 +427,18 @@ MachinaGUI::menu_import_midi()
Gtk::FILE_CHOOSER_ACTION_OPEN);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
+
+ Gtk::HBox* extra_widget = Gtk::manage(new Gtk::HBox());
+ Gtk::SpinButton* length_sb = Gtk::manage(new Gtk::SpinButton());
+ length_sb->set_increments(1, 10);
+ length_sb->set_range(0, INT_MAX);
+ length_sb->set_value(0);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("")), true, true);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("Maximum Length (0 = unlimited): ")), false, false);
+ extra_widget->pack_start(*length_sb, false, false);
+ dialog.set_extra_widget(*extra_widget);
+ extra_widget->show_all();
+
/*Gtk::HBox* extra_widget = Gtk::manage(new Gtk::HBox());
Gtk::SpinButton* track_sb = Gtk::manage(new Gtk::SpinButton());
@@ -444,7 +457,10 @@ MachinaGUI::menu_import_midi()
SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
//SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_uri(),
// track_sb->get_value_as_int());
- SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 0.0, 16.0);
+
+ double length = length_sb->get_value_as_int();
+
+ SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 0.0, length);
if (machine) {
dialog.hide();