diff options
author | David Robillard <d@drobilla.net> | 2007-03-03 04:40:05 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-03-03 04:40:05 +0000 |
commit | 43cca924857a2c9b8833d0f3e441a5d277ad42fe (patch) | |
tree | 86591a16c7f44674dbb264d245151086474995bd | |
parent | 085f3de0f526ac2ad7b00bfbc76be18b33a5c3c5 (diff) | |
download | machina-43cca924857a2c9b8833d0f3e441a5d277ad42fe.tar.gz machina-43cca924857a2c9b8833d0f3e441a5d277ad42fe.tar.bz2 machina-43cca924857a2c9b8833d0f3e441a5d277ad42fe.zip |
SMF writing work.
git-svn-id: http://svn.drobilla.net/lad/machina@343 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | src/engine/Engine.cpp | 17 | ||||
-rw-r--r-- | src/engine/JackDriver.cpp | 25 | ||||
-rw-r--r-- | src/engine/Machine.cpp | 26 | ||||
-rw-r--r-- | src/engine/Makefile.am | 1 | ||||
-rw-r--r-- | src/engine/MidiAction.cpp | 28 | ||||
-rw-r--r-- | src/engine/Node.cpp | 8 | ||||
-rw-r--r-- | src/engine/machina/Action.hpp | 9 | ||||
-rw-r--r-- | src/engine/machina/Engine.hpp | 1 | ||||
-rw-r--r-- | src/engine/machina/JackDriver.hpp | 8 | ||||
-rw-r--r-- | src/engine/machina/Machine.hpp | 13 | ||||
-rw-r--r-- | src/engine/machina/MidiAction.hpp | 10 | ||||
-rw-r--r-- | src/engine/machina/MidiDriver.hpp | 6 | ||||
-rw-r--r-- | src/engine/machina/Node.hpp | 6 | ||||
-rw-r--r-- | src/gui/MachinaGUI.cpp | 52 | ||||
-rw-r--r-- | src/gui/MachinaGUI.hpp | 4 | ||||
-rw-r--r-- | src/gui/machina.glade | 63 | ||||
-rw-r--r-- | src/gui/main.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 1 | ||||
-rwxr-xr-x | util/machina2dot.py | 3 |
19 files changed, 217 insertions, 66 deletions
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 2054b56..289abd3 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -15,9 +15,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <glibmm/ustring.h> #include "machina/Loader.hpp" #include "machina/Engine.hpp" #include "machina/JackDriver.hpp" +#include "machina/SMFDriver.hpp" namespace Machina { @@ -36,6 +38,21 @@ Engine::load_machine(const Glib::ustring& uri) } +/** Learn the SMF (MIDI) file at @a uri, and run the resulting machine + * (replacing current machine). + * Safe to call while engine is processing. + */ +SharedPtr<Machine> +Engine::learn_midi(const Glib::ustring& uri) +{ + SharedPtr<SMFDriver> file_driver(new SMFDriver()); + SharedPtr<Machine> m = file_driver->learn(uri); + m->activate(); + _driver->set_machine(m); + return m; +} + + void Engine::set_bpm(double bpm) { diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index a52cd91..b22ad85 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -26,7 +26,8 @@ namespace Machina { JackDriver::JackDriver(SharedPtr<Machine> machine) - : _machine(machine) + : _machine_changed(0) + , _machine(machine) , _input_port(NULL) , _output_port(NULL) , _cycle_time(1/48000.0, 120.0) @@ -87,6 +88,15 @@ JackDriver::detach() void +JackDriver::set_machine(SharedPtr<Machine> machine) +{ + _machine = machine; + if (is_activated()) + _machine_changed.wait(); +} + + +void JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time) { // We only actually read Jack input at the beginning of a cycle @@ -139,7 +149,7 @@ JackDriver::process_input(SharedPtr<Machine> machine, const TimeSlice& time) void JackDriver::write_event(Raul::BeatTime time, size_t size, - const byte* event) + const byte* event) throw (std::logic_error) { const TickCount nframes = _cycle_time.length_ticks(); const TickCount offset = _cycle_time.beats_to_ticks(time) @@ -180,20 +190,23 @@ JackDriver::on_process(jack_nframes_t nframes) /* Take a reference to machine here and use only it during the process * cycle so _machine can be switched with set_machine during a cycle. */ SharedPtr<Machine> machine = _machine; - + machine->set_sink(shared_from_this()); + // Machine was switched since last cycle, finalize old machine. if (_last_machine && machine != _last_machine) { _last_machine->reset(); // Exit all active states assert(_last_machine.use_count() > 1); // Realtime, can't delete _last_machine.reset(); // Cut our reference + _machine_changed.post(); // Signal we're done with it } + if (!machine) + return; + process_input(machine, _cycle_time); - if (machine->is_empty()) { - //cerr << "EMPTY\n"; + if (machine->is_empty()) return; - } while (true) { diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index 6cade39..e88a78e 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -38,6 +38,18 @@ Machine::~Machine() } +/** Set the MIDI sink to be used for executing MIDI actions. + * + * MIDI actions will silently do nothing unless this call is passed an + * existing Raul::MIDISink before running. + */ +void +Machine::set_sink(SharedPtr<Raul::MIDISink> sink) +{ + _sink = sink; +} + + void Machine::add_node(SharedPtr<Node> node) { @@ -55,7 +67,7 @@ Machine::reset() const SharedPtr<Node> node = (*n); if (node->is_active()) - node->exit(_time); + node->exit(_sink.lock(), _time); } } @@ -86,9 +98,9 @@ Machine::earliest_node() const /** Exit an active node at the current _time. */ void -Machine::exit_node(const SharedPtr<Node> node) +Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node) { - node->exit(_time); + node->exit(sink, _time); // Activate all successors to this node // (that aren't aready active right now) @@ -101,7 +113,7 @@ Machine::exit_node(const SharedPtr<Node> node) SharedPtr<Node> dst = (*s)->dst(); if (!dst->is_active()) - dst->enter(_time); + dst->enter(sink, _time); } } @@ -125,6 +137,8 @@ Machine::run(const Raul::TimeSlice& time) return 0; } + const SharedPtr<Raul::MIDISink> sink = _sink.lock(); + const BeatCount cycle_end = _time + time.length_beats(); //std::cerr << "Start: " << _time << std::endl; @@ -140,7 +154,7 @@ Machine::run(const Raul::TimeSlice& time) assert( ! (*n)->is_active()); if ((*n)->is_initial()) { - (*n)->enter(0); + (*n)->enter(sink, 0); entered = true; } @@ -170,7 +184,7 @@ Machine::run(const Raul::TimeSlice& time) < time.beats_to_ticks(cycle_end)) { this_time += earliest->exit_time() - _time; _time = earliest->exit_time(); - exit_node(earliest); + exit_node(sink, earliest); // Earliest active state ends in the future, done this cycle } else { diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index d500302..74308fd 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -14,5 +14,6 @@ libmachina_la_SOURCES = \ Loader.cpp \ MidiAction.cpp \ JackDriver.cpp \ + SMFDriver.cpp \ Engine.cpp \ LearnRequest.cpp diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp index ab73fd3..969e53a 100644 --- a/src/engine/MidiAction.cpp +++ b/src/engine/MidiAction.cpp @@ -17,13 +17,11 @@ #include <iostream> #include <raul/SharedPtr.h> +#include <raul/MIDISink.h> #include "machina/MidiAction.hpp" -#include "machina/MidiDriver.hpp" namespace Machina { -WeakPtr<MidiDriver> MidiAction::_driver; - /** Create a MIDI action. * @@ -50,18 +48,6 @@ MidiAction::~MidiAction() } -/** Set the MIDI driver to be used for executing MIDI actions. - * - * MIDI actions will silently do nothing unless this call is passed an - * existing MidiDriver. - */ -void -MidiAction::set_driver(SharedPtr<MidiDriver> driver) -{ - _driver = driver; -} - - /** Set the MIDI event to be emitted when the action executes. * * Returns pointer to old event (caller's responsibility to free if non-NULL). @@ -91,14 +77,13 @@ MidiAction::set_event(size_t size, const byte* new_event) * Safe to call concurrently with set_event. */ void -MidiAction::execute(Raul::BeatTime time) +MidiAction::execute(SharedPtr<Raul::MIDISink> sink, Raul::BeatTime time) { const byte* const event = _event.get(); if (event) { - SharedPtr<MidiDriver> driver = _driver.lock(); - if (driver) - driver->write_event(time, _size, event); + if (sink) + sink->write_event(time, _size, event); } else { std::cerr << "NULL MIDI ACTION"; } @@ -115,6 +100,11 @@ MidiAction::write_state(Raul::RDFWriter& writer) writer.write(_id, RdfId(RdfId::RESOURCE, "rdf:type"), RdfId(RdfId::RESOURCE, "machina:MidiAction")); + + // FIXME: Assumes note on/note off + writer.write(_id, + RdfId(RdfId::RESOURCE, "machina:midiNote"), + (int)(_event.get()[1])); } diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp index 7af2997..fbf02fe 100644 --- a/src/engine/Node.cpp +++ b/src/engine/Node.cpp @@ -63,22 +63,22 @@ Node::remove_exit_action(SharedPtr<Action> /*action*/) //using namespace std; void -Node::enter(BeatTime time) +Node::enter(SharedPtr<Raul::MIDISink> sink, BeatTime time) { //cerr << "ENTER " << time << endl; _is_active = true; _enter_time = time; if (_enter_action) - _enter_action->execute(time); + _enter_action->execute(sink, time); } void -Node::exit(BeatTime time) +Node::exit(SharedPtr<Raul::MIDISink> sink, BeatTime time) { //cerr << "EXIT " << time << endl; if (_exit_action) - _exit_action->execute(time); + _exit_action->execute(sink, time); _is_active = false; _enter_time = 0; } diff --git a/src/engine/machina/Action.hpp b/src/engine/machina/Action.hpp index 16c9b58..9ea106a 100644 --- a/src/engine/machina/Action.hpp +++ b/src/engine/machina/Action.hpp @@ -20,18 +20,21 @@ #include <string> #include <iostream> -#include <raul/Deletable.h> +#include <raul/MIDISink.h> #include <raul/TimeSlice.h> #include <raul/Stateful.h> +#include <raul/SharedPtr.h> #include "types.hpp" namespace Machina { +class MidiDriver; + /** An Action, executed on entering or exiting of a state. */ struct Action : public Raul::Deletable, public Raul::Stateful { - virtual void execute(Raul::BeatTime /*time*/) {} + virtual void execute(SharedPtr<Raul::MIDISink> sink, Raul::BeatTime time) = 0; virtual void write_state(Raul::RDFWriter& writer); }; @@ -41,7 +44,7 @@ class PrintAction : public Action { public: PrintAction(const std::string& msg) : _msg(msg) {} - void execute(Raul::BeatTime time) + void execute(SharedPtr<Raul::MIDISink>, Raul::BeatTime time) { std::cout << "t=" << time << ": " << _msg << std::endl; } private: diff --git a/src/engine/machina/Engine.hpp b/src/engine/machina/Engine.hpp index 37aa2db..32fab23 100644 --- a/src/engine/machina/Engine.hpp +++ b/src/engine/machina/Engine.hpp @@ -38,6 +38,7 @@ public: SharedPtr<Machine> machine() { return _driver->machine(); } SharedPtr<Machine> load_machine(const Glib::ustring& uri); + SharedPtr<Machine> learn_midi(const Glib::ustring& uri); void set_bpm(double bpm); void set_quantization(double beat_fraction); diff --git a/src/engine/machina/JackDriver.hpp b/src/engine/machina/JackDriver.hpp index 91f4106..0754741 100644 --- a/src/engine/machina/JackDriver.hpp +++ b/src/engine/machina/JackDriver.hpp @@ -21,6 +21,7 @@ #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" @@ -45,12 +46,12 @@ public: void attach(const std::string& client_name); void detach(); - SharedPtr<Machine> machine() { return _machine; } - void set_machine(SharedPtr<Machine> machine) { _machine = machine; } + SharedPtr<Machine> machine() { return _machine; } + void set_machine(SharedPtr<Machine> machine); void write_event(Raul::BeatTime time, size_t size, - const unsigned char* event); + const unsigned char* event) throw (std::logic_error); void set_bpm(double bpm) { _bpm.set(bpm); } void set_quantization(double quantization) { _quantization.set(quantization); } @@ -60,6 +61,7 @@ private: const Raul::TimeSlice& time); virtual void on_process(jack_nframes_t nframes); + Raul::Semaphore _machine_changed; SharedPtr<Machine> _machine; SharedPtr<Machine> _last_machine; diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp index 7b71d01..12b601d 100644 --- a/src/engine/machina/Machine.hpp +++ b/src/engine/machina/Machine.hpp @@ -61,16 +61,19 @@ public: typedef Raul::List<SharedPtr<Node> > Nodes; const Nodes& nodes() { return _nodes; } + void set_sink(SharedPtr<Raul::MIDISink> sink); + private: // Audio context SharedPtr<Node> earliest_node() const; - void exit_node(const SharedPtr<Node>); + void exit_node(const SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node>); - bool _is_activated; - bool _is_finished; - Raul::BeatTime _time; - Nodes _nodes; + WeakPtr<Raul::MIDISink> _sink; + bool _is_activated; + bool _is_finished; + Raul::BeatTime _time; + Nodes _nodes; //Raul::List<SharedPtr<LearnRequest> > _pending_learns; SharedPtr<LearnRequest> _pending_learn; diff --git a/src/engine/machina/MidiAction.hpp b/src/engine/machina/MidiAction.hpp index b62d841..2a9f91d 100644 --- a/src/engine/machina/MidiAction.hpp +++ b/src/engine/machina/MidiAction.hpp @@ -25,9 +25,9 @@ #include "types.hpp" #include "Action.hpp" -namespace Machina { +namespace Raul { class MIDISink; } -class MidiDriver; +namespace Machina { class MidiAction : public Action { @@ -43,11 +43,9 @@ public: return ret; } - static void set_driver(SharedPtr<MidiDriver> driver); - bool set_event(size_t size, const byte* event); - void execute(Raul::BeatTime time); + void execute(SharedPtr<Raul::MIDISink> driver, Raul::BeatTime time); virtual void write_state(Raul::RDFWriter& writer); @@ -55,8 +53,6 @@ private: MidiAction(size_t size, const unsigned char* event); - static WeakPtr<MidiDriver> _driver; - size_t _size; const size_t _max_size; Raul::AtomicPtr<byte> _event; diff --git a/src/engine/machina/MidiDriver.hpp b/src/engine/machina/MidiDriver.hpp index a4d9f51..a4d712c 100644 --- a/src/engine/machina/MidiDriver.hpp +++ b/src/engine/machina/MidiDriver.hpp @@ -18,6 +18,7 @@ #ifndef MACHINA_MIDIDRIVER_HPP #define MACHINA_MIDIDRIVER_HPP +#include <raul/TimeSlice.h> #include "machina/types.hpp" namespace Machina { @@ -25,14 +26,15 @@ namespace Machina { class Node; -class MidiDriver { +class MidiDriver : public Raul::MIDISink { public: virtual ~MidiDriver() {} /** Emit a MIDI event at the given time */ - virtual void write_event(Raul::BeatTime time, + /*virtual void write_event(Raul::BeatTime time, size_t size, const unsigned char* event) = 0; + */ /** Beginning of current cycle in absolute time. */ diff --git a/src/engine/machina/Node.hpp b/src/engine/machina/Node.hpp index 569a54e..bd1a66e 100644 --- a/src/engine/machina/Node.hpp +++ b/src/engine/machina/Node.hpp @@ -22,7 +22,7 @@ #include <raul/SharedPtr.h> #include <raul/List.h> #include <raul/Stateful.h> -#include <raul/TimeSlice.h> +#include <raul/MIDISink.h> #include "Action.hpp" namespace Machina { @@ -52,8 +52,8 @@ public: void add_exit_action(SharedPtr<Action> action); void remove_exit_action(SharedPtr<Action> action); - void enter(BeatTime time); - void exit(BeatTime time); + void enter(SharedPtr<Raul::MIDISink> driver, BeatTime time); + void exit(SharedPtr<Raul::MIDISink> driver, BeatTime time); void add_outgoing_edge(SharedPtr<Edge> edge); void remove_outgoing_edge(SharedPtr<Edge> edge); diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp index 3dd0c96..65ecb13 100644 --- a/src/gui/MachinaGUI.cpp +++ b/src/gui/MachinaGUI.cpp @@ -17,12 +17,13 @@ #include <cmath> #include <sstream> -#include <libgnomecanvasmm.h> -#include <libglademm/xml.h> #include <fstream> #include <pthread.h> +#include <libgnomecanvasmm.h> +#include <libglademm/xml.h> #include <raul/RDFWriter.h> #include <machina/Machine.hpp> +#include <machina/SMFDriver.hpp> #include "MachinaGUI.hpp" #include "MachinaCanvas.hpp" #include "NodeView.hpp" @@ -114,6 +115,8 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine) xml->get_widget("save_menuitem", _menu_file_save); xml->get_widget("save_as_menuitem", _menu_file_save_as); xml->get_widget("quit_menuitem", _menu_file_quit); + xml->get_widget("learn_midi_menuitem", _menu_learn_midi); + xml->get_widget("export_midi_menuitem", _menu_export_midi); xml->get_widget("view_toolbar_menuitem", _menu_view_toolbar); //xml->get_widget("view_refresh_menuitem", _menu_view_refresh); //xml->get_widget("view_messages_menuitem", _menu_view_messages); @@ -151,6 +154,10 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine) sigc::mem_fun(this, &MachinaGUI::menu_file_save_as)); _menu_file_quit->signal_activate().connect( sigc::mem_fun(this, &MachinaGUI::menu_file_quit)); + _menu_learn_midi->signal_activate().connect( + sigc::mem_fun(this, &MachinaGUI::menu_learn_midi)); + _menu_export_midi->signal_activate().connect( + sigc::mem_fun(this, &MachinaGUI::menu_export_midi)); //_menu_view_refresh->signal_activate().connect( // sigc::mem_fun(this, &MachinaGUI::menu_view_refresh)); _menu_view_toolbar->signal_toggled().connect( @@ -352,9 +359,7 @@ void MachinaGUI::menu_file_open() { Gtk::FileChooserDialog dialog(*_main_window, "Open Machine", 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); @@ -432,6 +437,45 @@ MachinaGUI::menu_file_save_as() void +MachinaGUI::menu_learn_midi() +{ + Gtk::FileChooserDialog dialog(*_main_window, "Learn from MIDI file", Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); + + const int result = dialog.run(); + + if (result == Gtk::RESPONSE_OK) { + SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver()); + SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_uri()); + } +} + + +void +MachinaGUI::menu_export_midi() +{ + Gtk::FileChooserDialog dialog(*_main_window, "Export to a MIDI file", Gtk::FILE_CHOOSER_ACTION_SAVE); + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); + + const int result = dialog.run(); + + if (result == Gtk::RESPONSE_OK) { + 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()); + file_driver->run(m, 32); // FIXME: hardcoded max length. TODO: solve halting problem + m->set_sink(_engine->driver()); + m->reset(); + _engine->driver()->activate(); + } +} + + +void MachinaGUI::on_pane_position_changed() { // avoid infinite recursion... diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp index 47142b0..962a6f9 100644 --- a/src/gui/MachinaGUI.hpp +++ b/src/gui/MachinaGUI.hpp @@ -59,6 +59,8 @@ protected: void menu_file_open(); void menu_file_save(); void menu_file_save_as(); + void menu_learn_midi(); + void menu_export_midi(); //void show_messages_toggled(); void show_toolbar_toggled(); //void menu_view_refresh(); @@ -98,6 +100,8 @@ protected: Gtk::MenuItem* _menu_file_save; Gtk::MenuItem* _menu_file_save_as; Gtk::MenuItem* _menu_file_quit; + Gtk::MenuItem* _menu_learn_midi; + Gtk::MenuItem* _menu_export_midi; Gtk::MenuItem* _menu_help_about; Gtk::CheckMenuItem* _menu_view_toolbar; //Gtk::CheckMenuItem* _menu_view_messages; diff --git a/src/gui/machina.glade b/src/gui/machina.glade index 6e5d7e9..d82f528 100644 --- a/src/gui/machina.glade +++ b/src/gui/machina.glade @@ -77,6 +77,34 @@ </child> <child> + <widget class="GtkImageMenuItem" id="export_midi_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Export MIDI...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_export_midi_menuitem_activate" last_modification_time="Fri, 02 Mar 2007 20:59:46 GMT"/> + <accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image6"> + <property name="visible">True</property> + <property name="stock">gtk-convert</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkSeparatorMenuItem" id="separator6"> + <property name="visible">True</property> + </widget> + </child> + + <child> <widget class="GtkImageMenuItem" id="quit_menuitem"> <property name="visible">True</property> <property name="label">gtk-quit</property> @@ -90,6 +118,41 @@ </child> <child> + <widget class="GtkMenuItem" id="machine_menu"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Machine</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="machine_menu_menu"> + + <child> + <widget class="GtkImageMenuItem" id="learn_midi_menuitem"> + <property name="visible">True</property> + <property name="label" translatable="yes">Learn MIDI...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_learn_midi_menuitem_activate" last_modification_time="Fri, 02 Mar 2007 21:00:16 GMT"/> + <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image7"> + <property name="visible">True</property> + <property name="stock">gtk-media-record</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> <widget class="GtkMenuItem" id="view_menu"> <property name="visible">True</property> <property name="label" translatable="yes">_View</property> diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 4e4bc07..3e7f737 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -34,8 +34,6 @@ main(int argc, char** argv) SharedPtr<JackDriver> driver(new JackDriver()); - MidiAction::set_driver(driver); - driver->attach("machina"); SharedPtr<Engine> engine(new Engine(driver)); diff --git a/src/main.cpp b/src/main.cpp index 9250738..f04a646 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,7 +53,6 @@ main(int argc, char** argv) } SharedPtr<JackDriver> driver(new JackDriver()); - MidiAction::set_driver(driver); Engine engine(driver); diff --git a/util/machina2dot.py b/util/machina2dot.py index f4e67ec..fc3c6b5 100755 --- a/util/machina2dot.py +++ b/util/machina2dot.py @@ -15,7 +15,8 @@ parser.parse_into_model(model, "file:" + sys.argv[1]) print """ digraph finite_state_machine { - rankdir=LR; + rankdir=TD; + size="20,20" node [shape = doublecircle, width = 1.25 ]; """, |