aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-03-19 23:16:47 +0000
committerDavid Robillard <d@drobilla.net>2007-03-19 23:16:47 +0000
commit9de593d8780ec6fec43703df7a532e65baa44510 (patch)
tree8aea0a26a3ee201ef1bdf3a11995976c4ad4ea0a
parent47f59aaad7a5ab8c189905544a761940ae9f8509 (diff)
downloadmachina-9de593d8780ec6fec43703df7a532e65baa44510.tar.gz
machina-9de593d8780ec6fec43703df7a532e65baa44510.tar.bz2
machina-9de593d8780ec6fec43703df7a532e65baa44510.zip
Learn quantization.
RDF serialziation to a C FILE*. Machina graph drawing improvements. git-svn-id: http://svn.drobilla.net/lad/machina@364 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/SMFDriver.cpp23
-rw-r--r--src/engine/machina/SMFDriver.hpp5
-rw-r--r--src/gui/MachinaGUI.cpp2
-rw-r--r--src/gui/main.cpp2
-rw-r--r--src/midi2machina.cpp7
-rwxr-xr-xutil/machina2dot13
6 files changed, 34 insertions, 18 deletions
diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp
index 60ee1af..fce43e6 100644
--- a/src/engine/SMFDriver.cpp
+++ b/src/engine/SMFDriver.cpp
@@ -18,6 +18,7 @@
#include <list>
#include <iostream>
#include <glibmm/convert.h>
+#include <raul/Quantizer.h>
#include <raul/SharedPtr.h>
#include <raul/midi_events.h>
#include <raul/SMFWriter.h>
@@ -46,7 +47,7 @@ SMFDriver::SMFDriver(SharedPtr<Machine> machine)
* @return the resulting machine.
*/
SharedPtr<Machine>
-SMFDriver::learn(const string& filename, unsigned track, Raul::BeatTime max_duration)
+SMFDriver::learn(const string& filename, unsigned track, double q, Raul::BeatTime max_duration)
{
SharedPtr<Machine> m(new Machine());
@@ -60,7 +61,7 @@ SMFDriver::learn(const string& filename, unsigned track, Raul::BeatTime max_dura
if (track > reader.num_tracks())
return SharedPtr<Machine>();
else
- learn_track(m, reader, track, max_duration);
+ learn_track(m, reader, track, q, max_duration);
if (m->nodes().size() > 1)
return m;
@@ -74,7 +75,7 @@ SMFDriver::learn(const string& filename, unsigned track, Raul::BeatTime max_dura
* This will result in a disjoint subgraph in the machine, one for each track.
*/
SharedPtr<Machine>
-SMFDriver::learn(const string& filename, Raul::BeatTime max_duration)
+SMFDriver::learn(const string& filename, double q, Raul::BeatTime max_duration)
{
SharedPtr<Machine> m(new Machine());
@@ -85,7 +86,7 @@ SMFDriver::learn(const string& filename, Raul::BeatTime max_duration)
}
for (unsigned t=1; t <= reader.num_tracks(); ++t) {
- learn_track(m, reader, t, max_duration);
+ learn_track(m, reader, t, q, max_duration);
}
if (m->nodes().size() > 1)
@@ -97,8 +98,9 @@ SMFDriver::learn(const string& filename, Raul::BeatTime max_duration)
void
SMFDriver::learn_track(SharedPtr<Machine> m,
- Raul::SMFReader& reader,
- unsigned track,
+ Raul::SMFReader& reader,
+ unsigned track,
+ double q,
Raul::BeatTime max_duration)
{
const bool found_track = reader.seek_to_track(track);
@@ -116,12 +118,14 @@ SMFDriver::learn_track(SharedPtr<Machine> m,
unsigned added_nodes = 0;
+ Raul::BeatTime unquantized_t = 0;
Raul::BeatTime t = 0;
unsigned char buf[4];
uint32_t ev_size;
uint32_t ev_time;
while (reader.read_event(4, buf, &ev_size, &ev_time) >= 0) {
- t += ev_time / (double)reader.ppqn();
+ unquantized_t += ev_time / (double)reader.ppqn();
+ t = Raul::Quantizer::quantize(q, unquantized_t);
if (max_duration != 0 && t > max_duration)
break;
@@ -204,7 +208,10 @@ SMFDriver::learn_track(SharedPtr<Machine> m,
}
if (added_nodes > 0)
- m->add_node(initial_node);
+ if (initial_node->outgoing_edges().size() == 1)
+ (*initial_node->outgoing_edges().begin())->dst()->set_initial(true);
+ else
+ m->add_node(initial_node);
}
diff --git a/src/engine/machina/SMFDriver.hpp b/src/engine/machina/SMFDriver.hpp
index 0d58db3..090eb02 100644
--- a/src/engine/machina/SMFDriver.hpp
+++ b/src/engine/machina/SMFDriver.hpp
@@ -37,8 +37,8 @@ class SMFDriver : public Driver,
public:
SMFDriver(SharedPtr<Machine> machine = SharedPtr<Machine>());
- SharedPtr<Machine> learn(const std::string& filename, Raul::BeatTime max_duration=0);
- SharedPtr<Machine> learn(const std::string& filename, unsigned track, Raul::BeatTime max_duration=0);
+ SharedPtr<Machine> learn(const std::string& filename, double q=0.0, Raul::BeatTime max_duration=0);
+ SharedPtr<Machine> learn(const std::string& filename, unsigned track, double q=0.0, Raul::BeatTime max_duration=0);
void run(SharedPtr<Machine> machine, Raul::BeatTime max_time);
@@ -58,6 +58,7 @@ private:
void learn_track(SharedPtr<Machine> machine,
Raul::SMFReader& reader,
unsigned track,
+ double q,
Raul::BeatTime max_duration=0);
};
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index 3d4676e..83a7504 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -424,7 +424,7 @@ 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(), 16.0);
+ SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 0.0, 16.0);
if (machine) {
dialog.hide();
diff --git a/src/gui/main.cpp b/src/gui/main.cpp
index 4185c45..5f208b4 100644
--- a/src/gui/main.cpp
+++ b/src/gui/main.cpp
@@ -42,7 +42,7 @@ main(int argc, char** argv)
string filename = argv[1];
cout << "Building machine from MIDI file " << filename << endl;
SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
- machine = file_driver->learn(filename, 0.0);
+ machine = file_driver->learn(filename);
}
// Build engine
diff --git a/src/midi2machina.cpp b/src/midi2machina.cpp
index d9377e7..6e6ffcb 100644
--- a/src/midi2machina.cpp
+++ b/src/midi2machina.cpp
@@ -48,14 +48,15 @@ catch_int(int)
int
main(int argc, char** argv)
{
- if (argc != 2) {
- cout << "Usage: " << argv[0] << " FILE" << endl;
+ if (argc != 3) {
+ cout << "Usage: midi2machina QUANTIZATION FILE" << endl;
+ cout << "Specify quantization in beats, e.g. 1.0, or 0 for none" << endl;
return -1;
}
SharedPtr<SMFDriver> driver(new SMFDriver());
- SharedPtr<Machine> machine = driver->learn(argv[1]);
+ SharedPtr<Machine> machine = driver->learn(argv[2], strtof(argv[1], NULL));
if (!machine) {
cout << "Failed to load MIDI file." << endl;
diff --git a/util/machina2dot b/util/machina2dot
index e3e420c..726f98a 100755
--- a/util/machina2dot
+++ b/util/machina2dot
@@ -39,7 +39,12 @@ for result in initial_nodes_query.execute(model):
node_durations[node_id] = duration
print "\t{ node [ style = invis ] ",
print "invis%d" % invis_id, " }"
- print '\t', node_id, "[ label = \"d =", duration, "\"];"
+
+ label = "d=%.1f" % duration
+ if result['note']:
+ label += "\\nn=%s" % result['note'].literal_value['string']
+
+ print '\t', node_id, "[ label=\"%s\" ]" % label
print '\t', "invis%d" % invis_id, " -> ", node_id
invis_id += 1
@@ -59,9 +64,11 @@ for result in nodes_query.execute(model):
node_id = result['n'].blank_identifier
duration = float(result['dur'].literal_value['string'])
node_durations[node_id] = duration
- label = "d=%.2f" % duration
+
+ label = "d=%.1f" % duration
if result['note']:
label += "\\nn=%s" % result['note'].literal_value['string']
+
print '\t', node_id, "[ label=\"%s\" ]" % label
@@ -79,6 +86,6 @@ for edge in edge_query.execute(model):
print '\t', edge['tail'].blank_identifier, ' -> ',
print edge['head'].blank_identifier, ' ',
print "[ label = \"%1.2f\"" % float(edge['prob'].literal_value['string']),
- print "minlen = ", node_durations[edge['tail'].blank_identifier] * 2, " ];"
+ print "minlen = ", node_durations[edge['tail'].blank_identifier], " ];"
print "}"