diff options
-rwxr-xr-x | autogen.sh | 2 | ||||
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/engine/JackDriver.cpp | 6 | ||||
-rw-r--r-- | src/engine/Machine.cpp | 16 | ||||
-rw-r--r-- | src/engine/Makefile.am | 6 | ||||
-rw-r--r-- | src/engine/SMFDriver.cpp | 26 | ||||
-rw-r--r-- | src/engine/machina/Driver.hpp | 25 | ||||
-rw-r--r-- | src/engine/machina/Engine.hpp | 11 | ||||
-rw-r--r-- | src/engine/machina/JackDriver.hpp | 12 | ||||
-rw-r--r-- | src/engine/machina/Makefile.am | 7 | ||||
-rw-r--r-- | src/engine/machina/MidiDriver.hpp | 56 | ||||
-rw-r--r-- | src/engine/machina/SMFDriver.hpp | 18 | ||||
-rw-r--r-- | src/gui/MachinaCanvas.cpp | 3 | ||||
-rw-r--r-- | src/gui/MachinaGUI.cpp | 10 | ||||
-rw-r--r-- | src/gui/Makefile.am | 3 | ||||
-rw-r--r-- | src/gui/main.cpp | 16 | ||||
-rw-r--r-- | src/midi2machina.cpp | 7 | ||||
-rwxr-xr-x | util/machina2dot (renamed from util/machina2dot.py) | 16 |
19 files changed, 157 insertions, 111 deletions
@@ -3,6 +3,6 @@ echo 'Generating necessary files...' libtoolize --copy --force aclocal-1.9 -#autoheader -Wall +autoheader automake-1.9 --gnu --add-missing autoconf diff --git a/configure.ac b/configure.ac index f56438e..72f8d43 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_SRCDIR([src/engine/Machine.cpp]) AC_CONFIG_SRCDIR([src/engine/machina/Machine.hpp]) AC_CONFIG_SRCDIR([src/gui/main.cpp]) -#AC_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADER([src/config.h]) AM_INIT_AUTOMAKE AC_LANG([C++]) @@ -15,10 +15,22 @@ AC_PROG_LIBTOOL AC_TYPE_SIZE_T -PKG_CHECK_MODULES(JACK, jack >= 0.102.20) PKG_CHECK_MODULES(RAUL, raul >= 0.0.0) PKG_CHECK_MODULES(GLIBMM, glibmm-2.4) +# Jack support +with_jack="yes" +AC_ARG_ENABLE(jack, + [AS_HELP_STRING(--enable-jack, [Enable Jack realtime processing (yes)])], + [ if test x$enable_jack = xno ; then with_jack=no ; fi ]) +if test "$with_jack" = "yes"; then + PKG_CHECK_MODULES(JACK, jack >= 0.102.20, with_jack="yes", with_jack="no") + if test "$with_jack" = "yes"; then + AC_DEFINE(WITH_JACK, 1, [Has JACK]) + fi +fi +AM_CONDITIONAL(WITH_JACK, [test "$with_jack" = "yes"]) + # Check for debugging flag debug="no" AC_ARG_ENABLE(debug, @@ -85,7 +97,8 @@ AC_MSG_RESULT([]) AC_MSG_RESULT([**********************************************************************]) AC_MSG_RESULT([Machina build configuration:]) AC_MSG_RESULT([]) -AC_MSG_RESULT([Super whiz-bang 2.0 Plus: oh yes]) +AC_MSG_RESULT([JACK supprt: $with_jack]) +AC_MSG_RESULT([GUI: $build_gui]) AC_MSG_RESULT([**********************************************************************]) AC_MSG_RESULT([]) diff --git a/src/Makefile.am b/src/Makefile.am index 1928c51..cdaad80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,10 +3,15 @@ SUBDIRS = engine gui -bin_PROGRAMS = machina midi2machina +bin_PROGRAMS = midi2machina + +if WITH_JACK +bin_PROGRAMS += machina +endif + +machina_SOURCES = machina.cpp AM_CXXFLAGS = @RAUL_CFLAGS@ @JACK_CFLAGS@ @GLIBMM_CFLAGS@ -I$(top_srcdir)/src/engine LDADD = @RAUL_LIBS@ @JACK_LIBS@ @GLIBMM_LIBS@ engine/libmachina.la -machina_SOURCES = machina.cpp midi2machina_SOURCES = midi2machina.cpp diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index 0261dd5..ee5a0d6 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -39,6 +39,12 @@ JackDriver::JackDriver(SharedPtr<Machine> machine) } +JackDriver::~JackDriver() +{ + detach(); +} + + void JackDriver::attach(const std::string& client_name) { diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index f76dd5c..844d2ce 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -22,6 +22,8 @@ #include "machina/Edge.hpp" #include "machina/MidiAction.hpp" +using namespace std; + namespace Machina { @@ -231,8 +233,12 @@ Machine::write_state(Raul::RDFWriter& writer) RdfId(RdfId::RESOURCE, "rdf:type"), RdfId(RdfId::RESOURCE, "machina:Machine")); + size_t count = 0; + for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { - + + cerr << "Writing node " << count++ << " state." << endl; + (*n)->write_state(writer); if ((*n)->is_initial()) { @@ -246,11 +252,17 @@ Machine::write_state(Raul::RDFWriter& writer) } } + count = 0; + for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { + + cerr << "Writing node " << count++ << " edges: "; for (Node::Edges::const_iterator e = (*n)->outgoing_edges().begin(); e != (*n)->outgoing_edges().end(); ++e) { + cerr << "."; + (*e)->write_state(writer); writer.write(RdfId(RdfId::RESOURCE, ""), @@ -258,6 +270,8 @@ Machine::write_state(Raul::RDFWriter& writer) (*e)->id()); } + cerr << endl; + } } diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 74308fd..eab7970 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -5,7 +5,6 @@ lib_LTLIBRARIES = libmachina.la libmachina_la_CXXFLAGS = @RAUL_CFLAGS@ @JACK_CFLAGS@ @GLIBMM_CFLAGS@ libmachina_la_LIBADD = @RAUL_LIBS@ @JACK_LIBS@ @GLIBMM_LIBS@ - libmachina_la_SOURCES = \ Node.cpp \ Edge.cpp \ @@ -13,7 +12,10 @@ libmachina_la_SOURCES = \ Machine.cpp \ Loader.cpp \ MidiAction.cpp \ - JackDriver.cpp \ SMFDriver.cpp \ Engine.cpp \ LearnRequest.cpp + +if WITH_JACK + JackDriver.cpp +endif diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp index cdf2ad7..60ee1af 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/SharedPtr.h> #include <raul/midi_events.h> #include <raul/SMFWriter.h> #include <raul/SMFReader.h> @@ -30,6 +31,13 @@ using namespace std; namespace Machina { +SMFDriver::SMFDriver(SharedPtr<Machine> machine) + : Driver(machine) +{ + _writer = SharedPtr<Raul::SMFWriter>(new Raul::SMFWriter()); +} + + /** Learn a single track from the MIDI file at @a uri * * @track selects which track of the MIDI file to import, starting from 1. @@ -43,7 +51,11 @@ SMFDriver::learn(const string& filename, unsigned track, Raul::BeatTime max_dura SharedPtr<Machine> m(new Machine()); Raul::SMFReader reader; - reader.open(filename); + + if (!reader.open(filename)) { + cerr << "Unable to open MIDI file " << filename << endl; + return SharedPtr<Machine>(); + } if (track > reader.num_tracks()) return SharedPtr<Machine>(); @@ -67,7 +79,10 @@ SMFDriver::learn(const string& filename, Raul::BeatTime max_duration) SharedPtr<Machine> m(new Machine()); Raul::SMFReader reader; - reader.open(filename); + if (!reader.open(filename)) { + cerr << "Unable to open MIDI file " << filename << endl; + return SharedPtr<Machine>(); + } for (unsigned t=1; t <= reader.num_tracks(); ++t) { learn_track(m, reader, t, max_duration); @@ -87,7 +102,8 @@ SMFDriver::learn_track(SharedPtr<Machine> m, Raul::BeatTime max_duration) { const bool found_track = reader.seek_to_track(track); - assert(found_track); + if (!found_track) + return; list<SharedPtr<Node> > active_nodes; @@ -113,7 +129,7 @@ SMFDriver::learn_track(SharedPtr<Machine> m, //cerr << "t = " << t << endl; if (ev_size > 0) { if ((buf[0] & 0xF0) == MIDI_CMD_NOTE_ON) { - cerr << "NOTE ON: " << (int)buf[1] << ", channel = " << (int)(buf[0] & 0x0F) << endl; + //cerr << "NOTE ON: " << (int)buf[1] << ", channel = " << (int)(buf[0] & 0x0F) << endl; SharedPtr<Node> node(new Node()); node->add_enter_action(SharedPtr<Action>(new MidiAction(ev_size, buf))); assert(connect_node_end_time <= t); @@ -195,7 +211,7 @@ SMFDriver::learn_track(SharedPtr<Machine> m, void SMFDriver::run(SharedPtr<Machine> machine, Raul::BeatTime max_time) { - Raul::TimeSlice time(1.0/(double)_ppqn, 120); + Raul::TimeSlice time(1.0/(double)_writer->ppqn(), 120); time.set_length(time.beats_to_ticks(max_time)); machine->set_sink(shared_from_this()); machine->run(time); diff --git a/src/engine/machina/Driver.hpp b/src/engine/machina/Driver.hpp index f2816ba..b900da0 100644 --- a/src/engine/machina/Driver.hpp +++ b/src/engine/machina/Driver.hpp @@ -15,22 +15,29 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MACHINA_JACKDRIVER_HPP -#define MACHINA_JACKDRIVER_HPP +#ifndef MACHINA_DRIVER_HPP +#define MACHINA_DRIVER_HPP -#include <raul/JackDriver.h> +#include <raul/MIDISink.h> -namespace Machine { +namespace Machina { +class Machine; -class JackDriver : public Raul::JackDriver { + +class Driver : public Raul::MIDISink { public: - JackDriver(SharedPtr<Machine> machine); + Driver(SharedPtr<Machine> machine) : _machine(machine) {} + virtual ~Driver() {} - virtual void set_machine(SharedPtr<Machine> machine); + SharedPtr<Machine> machine() { return _machine; } + virtual void set_machine(SharedPtr<Machine> machine) { _machine = machine; } + + virtual void set_bpm(double bpm) = 0; + virtual void set_quantization(double quantization) = 0; -protected: - virtual void on_process(jack_nframes_t nframes); + virtual void activate() {} + virtual void deactivate() {} private: SharedPtr<Machine> _machine; diff --git a/src/engine/machina/Engine.hpp b/src/engine/machina/Engine.hpp index 32fab23..82c21ba 100644 --- a/src/engine/machina/Engine.hpp +++ b/src/engine/machina/Engine.hpp @@ -20,22 +20,21 @@ #include <glibmm/ustring.h> #include <raul/SharedPtr.h> -#include "machina/JackDriver.hpp" +#include "machina/Driver.hpp" namespace Machina { class Machine; -class JackDriver; class Engine { public: - Engine(SharedPtr<JackDriver> driver) + Engine(SharedPtr<Driver> driver) : _driver(driver) { } - SharedPtr<JackDriver> driver() { return _driver; } - SharedPtr<Machine> machine() { return _driver->machine(); } + SharedPtr<Driver> driver() { return _driver; } + SharedPtr<Machine> machine() { return _driver->machine(); } SharedPtr<Machine> load_machine(const Glib::ustring& uri); SharedPtr<Machine> learn_midi(const Glib::ustring& uri); @@ -44,7 +43,7 @@ public: void set_quantization(double beat_fraction); private: - SharedPtr<JackDriver> _driver; + SharedPtr<Driver> _driver; }; diff --git a/src/engine/machina/JackDriver.hpp b/src/engine/machina/JackDriver.hpp index 0754741..13005c0 100644 --- a/src/engine/machina/JackDriver.hpp +++ b/src/engine/machina/JackDriver.hpp @@ -18,14 +18,15 @@ #ifndef MACHINA_JACKDRIVER_HPP #define MACHINA_JACKDRIVER_HPP +#include <boost/enable_shared_from_this.hpp> #include <raul/JackDriver.h> #include <raul/SharedPtr.h> #include <raul/DoubleBuffer.h> #include <raul/Semaphore.h> #include <jack/midiport.h> #include "Machine.hpp" -#include "MidiDriver.hpp" -#include <boost/enable_shared_from_this.hpp> +#include "Driver.hpp" + namespace Machina { @@ -38,15 +39,18 @@ class Node; * "Ticks" are individual frames when running under this driver, and all code * in the processing context must be realtime safe (non-blocking). */ -class JackDriver : public Raul::JackDriver, public Machina::MidiDriver, +class JackDriver : public Raul::JackDriver, + public Machina::Driver, public boost::enable_shared_from_this<JackDriver> { public: JackDriver(SharedPtr<Machine> machine = SharedPtr<Machine>()); void attach(const std::string& client_name); void detach(); + + void activate() { Raul::JackDriver::activate(); } + void deactivate() { Raul::JackDriver::deactivate(); } - SharedPtr<Machine> machine() { return _machine; } void set_machine(SharedPtr<Machine> machine); void write_event(Raul::BeatTime time, diff --git a/src/engine/machina/Makefile.am b/src/engine/machina/Makefile.am index 4501028..ff8eab5 100644 --- a/src/engine/machina/Makefile.am +++ b/src/engine/machina/Makefile.am @@ -7,8 +7,11 @@ libmachinainclude_HEADERS = \ Edge.hpp \ Machine.hpp \ Loader.hpp \ - JackDriver.hpp \ MidiAction.hpp \ - MidiDriver.hpp \ + Driver.hpp \ LearnRequest.hpp \ Engine.hpp + +if WITH_JACK + JackDriver.hpp +endif diff --git a/src/engine/machina/MidiDriver.hpp b/src/engine/machina/MidiDriver.hpp deleted file mode 100644 index a4d712c..0000000 --- a/src/engine/machina/MidiDriver.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Machina is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Machina is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MACHINA_MIDIDRIVER_HPP -#define MACHINA_MIDIDRIVER_HPP - -#include <raul/TimeSlice.h> -#include "machina/types.hpp" - -namespace Machina { - -class Node; - - -class MidiDriver : public Raul::MIDISink { -public: - virtual ~MidiDriver() {} - - /** Emit a MIDI event at the given time */ - /*virtual void write_event(Raul::BeatTime time, - size_t size, - const unsigned char* event) = 0; - */ - - /** Beginning of current cycle in absolute time. - */ - //virtual Raul::TickTime cycle_start() = 0; - - /** Length of current cycle in ticks. - * - * A "tick" is the smallest recognizable unit of (discrete) time. - * Ticks could be single audio frames, MIDI clock at a certain ppqn, etc. - */ - //virtual Raul::TickCount cycle_length() = 0; - -}; - - -} // namespace Machina - -#endif // MACHINA_MIDIDRIVER_HPP - diff --git a/src/engine/machina/SMFDriver.hpp b/src/engine/machina/SMFDriver.hpp index 3e74726..0d58db3 100644 --- a/src/engine/machina/SMFDriver.hpp +++ b/src/engine/machina/SMFDriver.hpp @@ -24,7 +24,7 @@ #include <raul/SMFWriter.h> #include <raul/SMFReader.h> #include "machina/types.hpp" -#include "machina/MidiDriver.hpp" +#include "machina/Driver.hpp" namespace Machina { @@ -32,15 +32,29 @@ class Node; class Machine; -class SMFDriver : public Raul::SMFWriter, +class SMFDriver : public Driver, public boost::enable_shared_from_this<SMFDriver> { 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); void run(SharedPtr<Machine> machine, Raul::BeatTime max_time); + + void write_event(Raul::BeatTime time, + size_t ev_size, + const unsigned char* ev) throw (std::logic_error) + { _writer->write_event(time, ev_size, ev); } + + void set_bpm(double /*bpm*/) { } + void set_quantization(double /*quantization*/) { } + + SharedPtr<Raul::SMFWriter> writer() { return _writer; } private: + SharedPtr<Raul::SMFWriter> _writer; + void learn_track(SharedPtr<Machine> machine, Raul::SMFReader& reader, unsigned track, diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp index c7d9843..34db1c1 100644 --- a/src/gui/MachinaCanvas.cpp +++ b/src/gui/MachinaCanvas.cpp @@ -194,6 +194,9 @@ MachinaCanvas::build(SharedPtr<Machina::Machine> machine) { destroy(); + if (!machine) + return; + std::map<SharedPtr<Machina::Node>, SharedPtr<NodeView> > views; for (Machina::Machine::Nodes::const_iterator i = machine->nodes().begin(); diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp index 0848f8b..3d4676e 100644 --- a/src/gui/MachinaGUI.cpp +++ b/src/gui/MachinaGUI.cpp @@ -303,13 +303,10 @@ MachinaGUI::status_message(const string& msg) /** Update the sensitivity status of menus to reflect the present. - * - * (eg. disable "Connect to Jack" when Machina is already connected to Jack) */ void MachinaGUI::connect_widgets() { - } using namespace std; @@ -427,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_uri(), 16.0); + SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 16.0); if (machine) { dialog.hide(); @@ -457,11 +454,12 @@ MachinaGUI::menu_export_midi() SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver()); _engine->driver()->deactivate(); const SharedPtr<Machina::Machine> m = _engine->machine(); - m->set_sink(file_driver); - file_driver->start(dialog.get_filename()); + m->set_sink(file_driver->writer()); + file_driver->writer()->start(dialog.get_filename()); file_driver->run(m, 32); // FIXME: hardcoded max length. TODO: solve halting problem m->set_sink(_engine->driver()); m->reset(); + file_driver->writer()->finish(); _engine->driver()->activate(); } } diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 5c6cf47..1d6390d 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,5 +1,4 @@ AM_CXXFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" @LIBGLADEMM_CFLAGS@ @GNOMECANVASMM_CFLAGS@ @JACK_CFLAGS@ @FLOWCANVAS_CFLAGS@ @RAUL_CFLAGS@ -I$(top_srcdir)/src/engine -machina_gui_LDADD = @FLOWCANVAS_LIBS@ @LIBGLADEMM_LIBS@ @GNOMECANVASMM_LIBS@ @JACK_LIBS@ @RAUL_CFLAGS@ ../engine/libmachina.la EXTRA_DIST = machina.gladep @@ -11,6 +10,8 @@ dist_sharefiles_DATA = machina.glade if WITH_GUI +machina_gui_LDADD = @FLOWCANVAS_LIBS@ @LIBGLADEMM_LIBS@ @GNOMECANVASMM_LIBS@ @JACK_LIBS@ @RAUL_CFLAGS@ ../engine/libmachina.la + bin_PROGRAMS = machina_gui machina_gui_SOURCES = \ main.cpp \ diff --git a/src/gui/main.cpp b/src/gui/main.cpp index b6dea9c..4185c45 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -19,11 +19,15 @@ #include <iostream> #include <string> #include <libgnomecanvasmm.h> +#include "../config.h" #include "machina/Loader.hpp" -#include "machina/JackDriver.hpp" #include "machina/SMFDriver.hpp" #include "MachinaGUI.hpp" +#ifdef WITH_JACK +#include "machina/JackDriver.hpp" +#endif + using namespace std; using namespace Machina; @@ -42,8 +46,14 @@ main(int argc, char** argv) } // Build engine - SharedPtr<JackDriver> driver(new JackDriver(machine)); + SharedPtr<Driver> driver; +#ifdef WITH_JACK + driver = SharedPtr<Driver>(new JackDriver(machine)); driver->attach("machina"); +#endif + if (!driver) + driver = SharedPtr<Driver>(new SMFDriver(machine)); + SharedPtr<Engine> engine(new Engine(driver)); // Launch GUI @@ -62,8 +72,6 @@ main(int argc, char** argv) return 1; } - driver->detach(); - return 0; } diff --git a/src/midi2machina.cpp b/src/midi2machina.cpp index fb5951f..d9377e7 100644 --- a/src/midi2machina.cpp +++ b/src/midi2machina.cpp @@ -62,6 +62,7 @@ main(int argc, char** argv) return -1; } + /* string out_filename = argv[1]; if (out_filename.find_last_of("/") != string::npos) out_filename = out_filename.substr(out_filename.find_last_of("/")+1); @@ -72,9 +73,11 @@ main(int argc, char** argv) out_filename += ".machina"; cout << "Writing output to " << out_filename << endl; - + */ + Raul::RDFWriter writer; - writer.start_to_filename(out_filename); + //writer.start_to_filename(out_filename); + writer.start_to_file_handle(stdout); machine->write_state(writer); writer.finish(); diff --git a/util/machina2dot.py b/util/machina2dot index cb704ef..e3e420c 100755 --- a/util/machina2dot.py +++ b/util/machina2dot @@ -12,7 +12,6 @@ if len(sys.argv) != 2: parser.parse_into_model(model, "file:" + sys.argv[1]) - print """ digraph finite_state_machine { rankdir=LR; @@ -23,10 +22,12 @@ node_durations = { } initial_nodes_query = RDF.SPARQLQuery(""" PREFIX machina: <http://drobilla.net/ns/machina#> -SELECT DISTINCT ?n ?dur WHERE { +SELECT DISTINCT ?n ?dur ?note WHERE { ?m machina:initialNode ?n . ?n a machina:Node ; machina:duration ?dur . + OPTIONAL { ?n machina:enterAction ?a . + ?a machina:midiNote ?note } } """) @@ -45,10 +46,12 @@ for result in initial_nodes_query.execute(model): nodes_query = RDF.SPARQLQuery(""" PREFIX machina: <http://drobilla.net/ns/machina#> -SELECT DISTINCT ?n ?dur WHERE { +SELECT DISTINCT ?n ?dur ?note WHERE { ?m machina:node ?n . ?n a machina:Node ; machina:duration ?dur . + OPTIONAL { ?n machina:enterAction ?a . + ?a machina:midiNote ?note } } """) @@ -56,7 +59,10 @@ 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 - print '\t', node_id, "[ label = \"d =", "%.2f" % duration, "\"]; " + label = "d=%.2f" % duration + if result['note']: + label += "\\nn=%s" % result['note'].literal_value['string'] + print '\t', node_id, "[ label=\"%s\" ]" % label edge_query = RDF.SPARQLQuery(""" @@ -72,7 +78,7 @@ SELECT DISTINCT ?tail ?head ?prob WHERE { 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 "[ label = \"%1.2f\"" % float(edge['prob'].literal_value['string']), print "minlen = ", node_durations[edge['tail'].blank_identifier] * 2, " ];" print "}" |