aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-12-07 17:27:06 +0000
committerDavid Robillard <d@drobilla.net>2007-12-07 17:27:06 +0000
commitaa11564fef8ed9330d42081288e8f310072c67d6 (patch)
tree3d092d0117fd8a309d4ec16e158893744a777362
parent885af895243b43220b1e99f1d3b2bebcc2ec6398 (diff)
downloadmachina-aa11564fef8ed9330d42081288e8f310072c67d6.tar.gz
machina-aa11564fef8ed9330d42081288e8f310072c67d6.tar.bz2
machina-aa11564fef8ed9330d42081288e8f310072c67d6.zip
Fix loading selector nodes.
Choosing evolution target MIDI from GUI. git-svn-id: http://svn.drobilla.net/lad/machina@963 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/Loader.cpp20
-rw-r--r--src/engine/MachineBuilder.cpp6
-rw-r--r--src/engine/Mutation.cpp6
-rw-r--r--src/engine/Problem.cpp4
-rw-r--r--src/engine/machina/Node.hpp2
-rw-r--r--src/engine/machina/Problem.hpp2
-rw-r--r--src/gui/MachinaGUI.cpp40
-rw-r--r--src/gui/MachinaGUI.hpp3
-rw-r--r--src/gui/machina.glade48
9 files changed, 107 insertions, 24 deletions
diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp
index 3b60223..cf41bd1 100644
--- a/src/engine/Loader.cpp
+++ b/src/engine/Loader.cpp
@@ -119,6 +119,26 @@ Loader::load(const Glib::ustring& uri)
}
+ /* Find out which nodes are selectors */
+
+ query = Query(_rdf_world, ustring(
+ "SELECT DISTINCT ?node WHERE {\n") +
+ machine_uri + " :node ?node .\n"
+ "?node a :SelectorNode .\n"
+ "}\n");
+
+ results = query.run(_rdf_world, model);
+
+ for (Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
+ const char* node_id = (*i)["node"];
+ Created::iterator n = created.find(node_id);
+ if (n != created.end())
+ n->second->set_selector(true);
+ else
+ cerr << "WARNING: Selector node " << node_id << " not found" << endl;
+ }
+
+
/* Get note actions */
query = Query(_rdf_world, ustring(
diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp
index 7f0da03..34e45b8 100644
--- a/src/engine/MachineBuilder.cpp
+++ b/src/engine/MachineBuilder.cpp
@@ -44,7 +44,7 @@ MachineBuilder::MachineBuilder(SharedPtr<Machine> machine, Raul::BeatTime q)
void
MachineBuilder::reset()
{
- _initial_node = SharedPtr<Node>(new Node());
+ _initial_node = SharedPtr<Node>(new Node(0.0));
_initial_node->set_initial(true);
_connect_node = _initial_node;
_connect_node_end_time = 0;
@@ -123,7 +123,7 @@ MachineBuilder::event(Raul::BeatTime time_offset,
if ((buf[0] & 0xF0) == MIDI_CMD_NOTE_ON) {
- SharedPtr<Node> node(new Node());
+ SharedPtr<Node> node(new Node(0.0));
node->set_enter_action(SharedPtr<Action>(new MidiAction(ev_size, buf)));
SharedPtr<Node> this_connect_node;
@@ -187,7 +187,7 @@ MachineBuilder::event(Raul::BeatTime time_offset,
// Finish a polyphonic section
if (_poly_nodes.size() > 0) {
- _connect_node = SharedPtr<Node>(new Node());
+ _connect_node = SharedPtr<Node>(new Node(0.0));
_machine->add_node(_connect_node);
connect_nodes(_machine, resolved, t, _connect_node, t);
diff --git a/src/engine/Mutation.cpp b/src/engine/Mutation.cpp
index d60ef34..a307ce5 100644
--- a/src/engine/Mutation.cpp
+++ b/src/engine/Mutation.cpp
@@ -52,10 +52,12 @@ AddNode::mutate(Machine& machine)
//cout << "ADD NODE" << endl;
// Create random node
- SharedPtr<Node> node(new Node(1.0));
+ SharedPtr<Node> node(new Node());
node->set_selector(true);
SharedPtr<Node> note_node = machine.random_node();
+ if (!note_node)
+ return;
uint8_t note = PtrCast<MidiAction>(note_node->enter_action())->event()[1];
node->set_enter_action(ActionFactory::note_on(note));
@@ -154,7 +156,7 @@ RemoveEdge::mutate(Machine& machine)
//cout << "REMOVE EDGE" << endl;
SharedPtr<Node> tail = machine.random_node();
- if (tail)
+ if (tail && !(tail->is_initial() && tail->edges().size() == 1))
tail->remove_edge(tail->random_edge());
}
diff --git a/src/engine/Problem.cpp b/src/engine/Problem.cpp
index 3fa793f..0db588c 100644
--- a/src/engine/Problem.cpp
+++ b/src/engine/Problem.cpp
@@ -42,7 +42,7 @@ Problem::Problem(const std::string& target_midi, SharedPtr<Machine> seed)
const bool opened = smf.open(target_midi);
assert(opened);
- smf.seek_to_track(2); // FIXME: kluge
+ smf.seek_to_track(2); // FIXME: ?
uint8_t buf[4];
uint32_t ev_size;
@@ -221,7 +221,7 @@ Problem::initial_population(size_t gene_size, size_t pop_size) const
for (uint8_t i=0; i < 128; ++i) {
if (_target._counts[i] > 0) {
//cout << "Initial note: " << (int)i << endl;
- SharedPtr<Node> node(new Node(1.0));
+ SharedPtr<Node> node(new Node(1/4.0));
node->set_enter_action(ActionFactory::note_on(i));
node->set_exit_action(ActionFactory::note_off(i));
node->set_selector(true);
diff --git a/src/engine/machina/Node.hpp b/src/engine/machina/Node.hpp
index 87e14af..04e7c07 100644
--- a/src/engine/machina/Node.hpp
+++ b/src/engine/machina/Node.hpp
@@ -44,7 +44,7 @@ class Node : public Raul::Stateful {
public:
typedef std::string ID;
- Node(BeatCount duration=1.0, bool initial=false);
+ Node(BeatCount duration=1/4.0, bool initial=false);
Node(const Node& copy);
void set_enter_action(SharedPtr<Action> action);
diff --git a/src/engine/machina/Problem.hpp b/src/engine/machina/Problem.hpp
index 7605e88..067be51 100644
--- a/src/engine/machina/Problem.hpp
+++ b/src/engine/machina/Problem.hpp
@@ -81,7 +81,7 @@ private:
};*/
struct Evaluator : public Raul::MIDISink {
- Evaluator(const Problem& problem) : _problem(problem), _order(8), _n_notes(0), _first_note(0) {
+ Evaluator(const Problem& problem) : _problem(problem), _order(4), _n_notes(0), _first_note(0) {
for (uint8_t i=0; i < 128; ++i)
_counts[i] = 0;
}
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index 0e872fd..4fdc6fa 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -78,6 +78,7 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
xml->get_widget("zoom_normal_but", _zoom_normal_button);
xml->get_widget("zoom_full_but", _zoom_full_button);
xml->get_widget("arrange_but", _arrange_button);
+ xml->get_widget("load_target_but", _load_target_button);
xml->get_widget("evolve_but", _evolve_button);
xml->get_widget("mutate_but", _mutate_button);
xml->get_widget("compress_but", _compress_button);
@@ -174,6 +175,7 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::idle_callback), 100);
#ifdef HAVE_EUGENE
+ _load_target_button->signal_clicked().connect(sigc::mem_fun(this, &MachinaGUI::load_target_clicked));
_evolve_button->signal_clicked().connect(sigc::mem_fun(this, &MachinaGUI::evolve_toggled));
Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::evolve_callback), 1000);
#else
@@ -252,10 +254,31 @@ MachinaGUI::arrange()
void
+MachinaGUI::load_target_clicked()
+{
+ Gtk::FileChooserDialog dialog(*_main_window,
+ "Load MIDI file for evolution", Gtk::FILE_CHOOSER_ACTION_OPEN);
+ dialog.set_local_only(false);
+ dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
+
+ Gtk::FileFilter filt;
+ filt.add_pattern("*.mid");
+ filt.set_name("MIDI Files");
+ dialog.set_filter(filt);
+
+ const int result = dialog.run();
+
+ if (result == Gtk::RESPONSE_OK)
+ _target_filename = dialog.get_filename();
+}
+
+
+void
MachinaGUI::evolve_toggled()
{
if (_evolve_button->get_active()) {
- _evolver = SharedPtr<Evolver>(new Evolver("target.mid", _engine->machine()));
+ _evolver = SharedPtr<Evolver>(new Evolver(_target_filename, _engine->machine()));
_evolve = true;
stop_clicked();
_engine->driver()->set_machine(SharedPtr<Machine>());
@@ -384,6 +407,11 @@ MachinaGUI::menu_file_open()
dialog.set_local_only(false);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
+
+ Gtk::FileFilter filt;
+ filt.add_pattern("*.machina.ttl");
+ filt.set_name("Machina Machines (Turtle/RDF)");
+ dialog.set_filter(filt);
const int result = dialog.run();
@@ -477,6 +505,11 @@ MachinaGUI::menu_import_midi()
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
+ Gtk::FileFilter filt;
+ filt.add_pattern("*.mid");
+ filt.set_name("MIDI Files");
+ dialog.set_filter(filt);
+
Gtk::HBox* extra_widget = Gtk::manage(new Gtk::HBox());
Gtk::SpinButton* length_sb = Gtk::manage(new Gtk::SpinButton());
length_sb->set_increments(1, 10);
@@ -520,6 +553,11 @@ MachinaGUI::menu_export_midi()
Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
+
+ Gtk::FileFilter filt;
+ filt.add_pattern("*.mid");
+ filt.set_name("MIDI Files");
+ dialog.set_filter(filt);
const int result = dialog.run();
diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp
index 3b6c340..26cfad4 100644
--- a/src/gui/MachinaGUI.hpp
+++ b/src/gui/MachinaGUI.hpp
@@ -63,6 +63,7 @@ protected:
void menu_help_about();
void menu_help_help();
void arrange();
+ void load_target_clicked();
void evolve_toggled();
void random_mutation(SharedPtr<Machina::Machine> machine);
void mutate(SharedPtr<Machina::Machine> machine, unsigned mutation);
@@ -83,6 +84,7 @@ protected:
bool _evolve;
string _save_uri;
+ string _target_filename;
boost::shared_ptr<MachinaCanvas> _canvas;
boost::shared_ptr<Machina::Engine> _engine;
@@ -121,6 +123,7 @@ protected:
Gtk::ToolButton* _zoom_normal_button;
Gtk::ToolButton* _zoom_full_button;
Gtk::ToolButton* _arrange_button;
+ Gtk::ToolButton* _load_target_button;
Gtk::ToggleToolButton* _evolve_button;
Gtk::ToolButton* _mutate_button;
Gtk::ToolButton* _compress_button;
diff --git a/src/gui/machina.glade b/src/gui/machina.glade
index e91553d..f991a08 100644
--- a/src/gui/machina.glade
+++ b/src/gui/machina.glade
@@ -404,6 +404,26 @@
<property name="icon_size">GTK_ICON_SIZE_SMALL_TOOLBAR</property>
<property name="icon_size_set">True</property>
<child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton7">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="load_target_but">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip" translatable="yes">Load MIDI file as evolutionary goal</property>
+ <property name="stock_id">gtk-open</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkSeparatorToolItem" id="toolbutton5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -704,58 +724,58 @@ Selector nodes are shown in green.
<property name="column_spacing">4</property>
<property name="row_spacing">8</property>
<child>
- <widget class="GtkSpinButton" id="node_properties_note_spinbutton">
+ <widget class="GtkSpinButton" id="node_properties_duration_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="adjustment">60 0 127 1 10 10</property>
+ <property name="has_focus">True</property>
+ <property name="adjustment">1 0 999999 1 10 10</property>
<property name="climb_rate">1</property>
+ <property name="digits">2</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label6">
+ <widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Note: </property>
+ <property name="label" translatable="yes">Duration: </property>
</widget>
<packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label7">
+ <widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Duration: </property>
+ <property name="label" translatable="yes">Note: </property>
</widget>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkSpinButton" id="node_properties_duration_spinbutton">
+ <widget class="GtkSpinButton" id="node_properties_note_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="adjustment">1 0 999999 1 10 10</property>
+ <property name="adjustment">60 0 127 1 10 10</property>
<property name="climb_rate">1</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>