diff options
author | David Robillard <d@drobilla.net> | 2007-02-11 01:26:07 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-02-11 01:26:07 +0000 |
commit | da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74 (patch) | |
tree | 8371f2d2e46925df9337be9b578cfb74d671d285 /src | |
parent | cee33ba4c0859b117be94df6ccbf3eb756a850af (diff) | |
download | machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.tar.gz machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.tar.bz2 machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.zip |
Moved Maid from Ingen to Raul.
Working machina MIDI learn, fixes, etc, etc.
git-svn-id: http://svn.drobilla.net/lad/machina@302 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/JackDriver.cpp | 87 | ||||
-rw-r--r-- | src/engine/JackNodeFactory.cpp | 10 | ||||
-rw-r--r-- | src/engine/Machine.cpp | 114 | ||||
-rw-r--r-- | src/engine/MidiAction.cpp | 27 | ||||
-rw-r--r-- | src/engine/Node.cpp | 19 | ||||
-rw-r--r-- | src/engine/machina/Action.hpp | 5 | ||||
-rw-r--r-- | src/engine/machina/JackDriver.hpp | 8 | ||||
-rw-r--r-- | src/engine/machina/Machine.hpp | 16 | ||||
-rw-r--r-- | src/engine/machina/Makefile.am | 3 | ||||
-rw-r--r-- | src/engine/machina/MidiAction.hpp | 22 | ||||
-rw-r--r-- | src/engine/machina/Node.hpp | 22 | ||||
-rw-r--r-- | src/gui/MachinaCanvas.cpp | 21 | ||||
-rw-r--r-- | src/gui/MachinaCanvas.hpp | 8 | ||||
-rw-r--r-- | src/gui/MachinaGUI.cpp | 38 | ||||
-rw-r--r-- | src/gui/MachinaGUI.hpp | 7 | ||||
-rw-r--r-- | src/gui/main.cpp | 3 | ||||
-rw-r--r-- | src/main.cpp | 24 |
17 files changed, 221 insertions, 213 deletions
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index ff78520..fefa4d2 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -16,6 +16,7 @@ */ #include <iostream> +#include <iomanip> #include "machina/JackDriver.hpp" #include "machina/MidiAction.hpp" @@ -34,18 +35,24 @@ JackDriver::JackDriver() void JackDriver::attach(const std::string& client_name) { - Raul::JackDriver::attach(client_name, "debug"); + Raul::JackDriver::attach(client_name); if (jack_client()) { _input_port = jack_port_register(jack_client(), - "out", + "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + + if (!_input_port) + std:: cerr << "WARNING: Failed to create MIDI input port." << std::endl; _output_port = jack_port_register(jack_client(), "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); + + if (!_output_port) + std::cerr << "WARNING: Failed to create MIDI output port." << std::endl; } } @@ -74,17 +81,10 @@ JackDriver::stamp_to_offset(Timestamp stamp) void -JackDriver::learn(SharedPtr<Node> node) -{ - _learn_enter_action = SharedPtr<MidiAction>(new MidiAction(shared_from_this(), 4, NULL)); - _learn_exit_action = SharedPtr<MidiAction>(new MidiAction(shared_from_this(), 4, NULL)); - _learn_node = node; -} - - -void JackDriver::process_input(jack_nframes_t nframes) { + using namespace std; + //if (_learn_node) { void* jack_buffer = jack_port_get_buffer(_input_port, nframes); const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer, nframes); @@ -93,7 +93,33 @@ JackDriver::process_input(jack_nframes_t nframes) jack_midi_event_t ev; jack_midi_event_get(&ev, jack_buffer, i, nframes); - std::cerr << "EVENT: " << (char)ev.buffer[0] << "\n"; + if (ev.buffer[0] == 0x90) { + cerr << "NOTE ON\n"; + + const SharedPtr<LearnRequest> learn = _machine->pending_learn(); + if (learn) { + learn->enter_action()->set_event(ev.size, ev.buffer); + cerr << "LEARN START\n"; + learn->start(jack_last_frame_time(_client) + ev.time); + //LearnRecord learn = _machine->pop_learn(); + } + + } else if (ev.buffer[0] == 0x80) { + cerr << "NOTE OFF\n"; + + const SharedPtr<LearnRequest> learn = _machine->pending_learn(); + + if (learn) { + if (learn->started()) { + learn->exit_action()->set_event(ev.size, ev.buffer); + learn->finish(jack_last_frame_time(_client) + ev.time); + _machine->clear_pending_learn(); + cerr << "LEARNED!\n"; + } + } + } + + //std::cerr << "EVENT: " << std::hex << (int)ev.buffer[0] << "\n"; } //} @@ -108,6 +134,7 @@ JackDriver::write_event(Timestamp time, const FrameCount nframes = _current_cycle_nframes; const FrameCount offset = stamp_to_offset(time); + assert(_output_port); jack_midi_event_write( jack_port_get_buffer(_output_port, nframes), offset, event, size, nframes); @@ -117,25 +144,35 @@ JackDriver::write_event(Timestamp time, void JackDriver::on_process(jack_nframes_t nframes) { - //std::cerr << "======================================================\n"; + using namespace std; + //std::cerr << "> ======================================================\n"; _current_cycle_offset = 0; _current_cycle_nframes = nframes; + assert(_output_port); jack_midi_clear_buffer(jack_port_get_buffer(_output_port, nframes), nframes); + process_input(nframes); + + if (_machine->is_empty()) { + //cerr << "EMPTY\n"; + return; + } + while (true) { - bool machine_done = ! _machine->run(_current_cycle_nframes); + const FrameCount run_duration = _machine->run(_current_cycle_nframes); - if (machine_done && _machine->is_finished()) + // Machine didn't run at all (empty, or no initial states) + if (run_duration == 0) { + _machine->reset(); // Try again next cycle + _current_cycle_start = 0; return; + } - if (!machine_done) { - _current_cycle_start += _current_cycle_nframes; - break; - - } else { + // Machine ran for portion of cycle + else if (run_duration < _current_cycle_nframes) { const Timestamp finish_time = _machine->time(); const FrameCount finish_offset = stamp_to_offset(finish_time); @@ -146,10 +183,18 @@ JackDriver::on_process(jack_nframes_t nframes) _current_cycle_nframes -= _current_cycle_offset; _current_cycle_start = 0; _machine->reset(); + + // Machine ran for entire cycle + } else { + if (_machine->is_finished()) + _machine->reset(); + + _current_cycle_start += _current_cycle_nframes; + break; } } - //std::cerr << "======================================================\n"; + //std::cerr << "< ======================================================\n"; } diff --git a/src/engine/JackNodeFactory.cpp b/src/engine/JackNodeFactory.cpp index ac99422..55c7ff2 100644 --- a/src/engine/JackNodeFactory.cpp +++ b/src/engine/JackNodeFactory.cpp @@ -28,19 +28,19 @@ JackNodeFactory::create_node(Node::ID, byte note, FrameCount duration) { // FIXME: obviously leaks like a sieve - size_t event_size = 3; - static const byte note_on[3] = { 0x80, note, 0x40 }; + //size_t event_size = 3; + //static const byte note_on[3] = { 0x80, note, 0x40 }; Node* n = new Node(duration); - MidiAction* a_enter = new MidiAction(_driver, event_size, note_on); + /*SharedPtr<MidiAction> a_enter = MidiAction::create(event_size, note_on); static const byte note_off[3] = { 0x90, note, 0x40 }; - MidiAction* a_exit = new MidiAction(_driver, event_size, note_off); + SharedPtr<MidiAction> a_exit = MidiAction::create(event_size, note_off); n->add_enter_action(a_enter); n->add_exit_action(a_exit); - +*/ return SharedPtr<Node>(n); } diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index 3f28414..476e3d1 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -15,10 +15,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <algorithm> +#include "raul/SharedPtr.h" #include "machina/Machine.hpp" #include "machina/Node.hpp" #include "machina/Edge.hpp" +#include "machina/MidiAction.hpp" namespace Machina { @@ -103,25 +104,27 @@ Machine::exit_node(const SharedPtr<Node> node) /** Run the machine for @a nframes frames. * - * Returns false when the machine has finished running (i.e. there are - * no currently active states). - * - * If this returns false, time() will return the exact time stamp the + * Returns the duration of time the machine actually ran (from 0 to nframes). + * Caller can check is_finished() to determine if the machine still has any + * active states. If not, time() will return the exact time stamp the * machine actually finished on (so it can be restarted immediately * with sample accuracy if necessary). */ -bool +FrameCount Machine::run(FrameCount nframes) { - if (_is_finished) - return false; + using namespace std; + if (_is_finished) { + cerr << "FINISHED\n"; + return 0; + } const FrameCount cycle_end = _time + nframes; + //std::cerr << "Start: " << _time << std::endl; + assert(_is_activated); - //std::cerr << "--------- " << _time << " - " << _time + nframes << std::endl; - // Initial run, enter all initial states if (_time == 0) { bool entered = false; @@ -131,16 +134,19 @@ Machine::run(FrameCount nframes) (*n)->enter(0); entered = true; } else { - (*n)->exit(0); + if ((*n)->is_active()) + (*n)->exit(0); } } } if (!entered) { - _is_finished = false; // run next time - return false; // but done this cycle + _is_finished = true; + return 0; } } + FrameCount this_time = 0; + while (true) { SharedPtr<Node> earliest = earliest_node(); @@ -148,83 +154,45 @@ Machine::run(FrameCount nframes) // No more active states, machine is finished if (!earliest) { _is_finished = true; - return false; + break; // Earliest active state ends this cycle } else if (earliest->exit_time() < cycle_end) { + this_time += earliest->exit_time() - _time; _time = earliest->exit_time(); exit_node(earliest); // Earliest active state ends in the future, done this cycle } else { _time = cycle_end; - return true; + this_time = nframes; // ran the entire cycle + break; } } -#if 0 - while (!done) { - - done = true; - - for (std::vector<Node*>::iterator i = _voices.begin(); - i != _voices.end(); ++i) { - - Node* const n = *i; - - // Active voice which ends within this cycle, transition - if (n && n->is_active() && n->end_time() < cycle_end) { - // Guaranteed to be within this cycle - const FrameCount end_time = std::max(_time, n->end_time()); - n->exit(std::max(_time, n->end_time())); - done = false; - - // Greedily grab one of the successors with the voice already - // on this node so voices follow paths nicely - for (Node::EdgeList::const_iterator s = n->outgoing_edges().begin(); - s != n->outgoing_edges().end(); ++s) { - Node* dst = (*s)->dst(); - if (!dst->is_active()) { - dst->enter(end_time); - *i = dst; - break; - } - } + //std::cerr << "Done: " << this_time << std::endl; - latest_event = end_time; - } + assert(this_time <= nframes); + return this_time; +} - } - // FIXME: use free voices to claim any 'free successors' - // (when nodes have multiple successors and one gets chosen in the - // greedy bit above) - - // If every voice is on the initial node... - bool is_reset = true; - for (std::vector<Node*>::iterator i = _voices.begin(); - i != _voices.end(); ++i) - if ((*i) != NULL && (*i)->is_active()) - is_reset = false; - - // ... then start - if (is_reset) { - - std::vector<Node*>::iterator n = _voices.begin(); - for (Node::EdgeList::const_iterator s = _initial_node->outgoing_edges().begin(); - s != _initial_node->outgoing_edges().end() && n != _voices.end(); - ++s, ++n) { - (*s)->dst()->enter(latest_event); - done = false; - *n = (*s)->dst(); - } - } - } - _time += nframes; +/** Push a node onto the learn stack. + * + * NOT realtime (actions are allocated here). + */ +void +Machine::learn(SharedPtr<LearnRequest> learn) +{ + std::cerr << "LEARN\n"; + + /*LearnRequest request(node, + SharedPtr<MidiAction>(new MidiAction(4, NULL)), + SharedPtr<MidiAction>(new MidiAction(4, NULL)));*/ - return false; -#endif + //_pending_learns.push_back(learn); + _pending_learn = learn; } diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp index 9d30151..aca4b75 100644 --- a/src/engine/MidiAction.cpp +++ b/src/engine/MidiAction.cpp @@ -22,6 +22,8 @@ namespace Machina { +WeakPtr<MidiDriver> MidiAction::_driver; + /** Create a MIDI action. * @@ -31,11 +33,9 @@ namespace Machina { * Memory management of @event is the caller's responsibility * (ownership is not taken). */ -MidiAction::MidiAction(WeakPtr<MidiDriver> driver, - size_t size, - const byte* event) - : _driver(driver) - , _size(0) +MidiAction::MidiAction(size_t size, + const byte* event) + : _size(0) , _max_size(size) { _event = new byte[_max_size]; @@ -50,6 +50,18 @@ 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). @@ -63,7 +75,7 @@ MidiAction::set_event(size_t size, const byte* new_event) byte* const event = _event.get(); if (size <= _max_size) { _event = NULL; - if (size > 0) + if (size > 0 && new_event) memcpy(event, new_event, size); _size = size; _event = event; @@ -86,7 +98,6 @@ MidiAction::execute(Timestamp time) using namespace std; if (event) { - cerr << "MIDI FIRING"; SharedPtr<MidiDriver> driver = _driver.lock(); if (driver) driver->write_event(time, _size, event); @@ -98,4 +109,4 @@ MidiAction::execute(Timestamp time) } // namespace Machina - + diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp index def7a70..59af04e 100644 --- a/src/engine/Node.cpp +++ b/src/engine/Node.cpp @@ -27,46 +27,44 @@ Node::Node(FrameCount duration, bool initial) , _is_active(false) , _enter_time(0) , _duration(duration) - , _enter_action(NULL) - , _exit_action(NULL) { } void -Node::add_enter_action(Action* action) +Node::add_enter_action(SharedPtr<Action> action) { - assert(!_enter_action); _enter_action = action; } void -Node::remove_enter_action(Action* /*action*/) +Node::remove_enter_action(SharedPtr<Action> /*action*/) { - _enter_action = NULL; + _enter_action.reset(); } void -Node::add_exit_action(Action* action) +Node::add_exit_action(SharedPtr<Action> action) { - assert(!_exit_action); _exit_action = action; } void -Node::remove_exit_action(Action* /*action*/) +Node::remove_exit_action(SharedPtr<Action> /*action*/) { - _exit_action = NULL; + _exit_action.reset(); } +//using namespace std; void Node::enter(Timestamp time) { + //cerr << "ENTER " << time << endl; _is_active = true; _enter_time = time; if (_enter_action) @@ -77,6 +75,7 @@ Node::enter(Timestamp time) void Node::exit(Timestamp time) { + //cerr << "EXIT " << time << endl; if (_exit_action) _exit_action->execute(time); _is_active = false; diff --git a/src/engine/machina/Action.hpp b/src/engine/machina/Action.hpp index feb0e0b..984a1a0 100644 --- a/src/engine/machina/Action.hpp +++ b/src/engine/machina/Action.hpp @@ -20,6 +20,7 @@ #include <string> #include <iostream> +#include <raul/Deletable.h> #include "types.hpp" namespace Machina { @@ -29,9 +30,7 @@ namespace Machina { * * Actions do not have time as a property. */ -struct Action { - virtual ~Action() {} - +struct Action : public Raul::Deletable { virtual void execute(Timestamp /*time*/) {} }; diff --git a/src/engine/machina/JackDriver.hpp b/src/engine/machina/JackDriver.hpp index 9a72a62..e1f809f 100644 --- a/src/engine/machina/JackDriver.hpp +++ b/src/engine/machina/JackDriver.hpp @@ -50,8 +50,6 @@ public: Timestamp cycle_start() { return _current_cycle_start; } FrameCount cycle_length() { return _current_cycle_nframes; } - void learn(SharedPtr<Node> node); - void write_event(Timestamp time, size_t size, const unsigned char* event); @@ -66,13 +64,9 @@ private: SharedPtr<Machine> _machine; - SharedPtr<Node> _learn_node; - SharedPtr<MidiAction> _learn_enter_action; - SharedPtr<MidiAction> _learn_exit_action; - jack_port_t* _input_port; jack_port_t* _output_port; - Timestamp _current_cycle_start; + Timestamp _current_cycle_start; ///< in machine relative time Timestamp _current_cycle_offset; ///< for split cycles FrameCount _current_cycle_nframes; }; diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp index 4036ef3..b53f55c 100644 --- a/src/engine/machina/Machine.hpp +++ b/src/engine/machina/Machine.hpp @@ -18,11 +18,10 @@ #ifndef MACHINA_MACHINE_HPP #define MACHINA_MACHINE_HPP -#include <vector> -#include <map> #include <raul/SharedPtr.h> #include <raul/List.h> #include "types.hpp" +#include "LearnRequest.hpp" #include "Node.hpp" namespace Machina { @@ -37,16 +36,24 @@ public: void activate() { _is_activated = true; } void deactivate() { _is_activated = false; } + bool is_empty() { return _nodes.empty(); } bool is_finished() { return _is_finished; } void add_node(SharedPtr<Node> node); + void learn(SharedPtr<LearnRequest> learn); // Audio context void reset(); - bool run(FrameCount nframes); + FrameCount run(FrameCount nframes); // Any context FrameCount time() { return _time; } + + + //LearnRequest pop_learn() { return _pending_learns.pop_front(); } + //SharedPtr<LearnRequest> first_learn() { return *_pending_learns.begin(); } + SharedPtr<LearnRequest> pending_learn() { return _pending_learn; } + void clear_pending_learn() { _pending_learn.reset(); } private: typedef Raul::List<SharedPtr<Node> > Nodes; @@ -59,6 +66,9 @@ private: bool _is_finished; FrameCount _time; Nodes _nodes; + + //Raul::List<SharedPtr<LearnRequest> > _pending_learns; + SharedPtr<LearnRequest> _pending_learn; }; diff --git a/src/engine/machina/Makefile.am b/src/engine/machina/Makefile.am index ffcae1e..7bdd1fd 100644 --- a/src/engine/machina/Makefile.am +++ b/src/engine/machina/Makefile.am @@ -10,4 +10,5 @@ libmachinainclude_HEADERS = \ NodeFactory.hpp \ JackNodeFactory.hpp \ MidiAction.hpp \ - MidiDriver.hpp + MidiDriver.hpp \ + LearnRequest.hpp diff --git a/src/engine/machina/MidiAction.hpp b/src/engine/machina/MidiAction.hpp index d362a63..7dff692 100644 --- a/src/engine/machina/MidiAction.hpp +++ b/src/engine/machina/MidiAction.hpp @@ -18,6 +18,7 @@ #ifndef MACHINA_MIDIACTION_HPP #define MACHINA_MIDIACTION_HPP +#include <raul/Maid.h> #include <raul/WeakPtr.h> #include <raul/AtomicPtr.h> #include "types.hpp" @@ -30,18 +31,29 @@ class MidiDriver; class MidiAction : public Action { public: - MidiAction(WeakPtr<MidiDriver> driver, - size_t size, - const unsigned char* event); - ~MidiAction(); + + static SharedPtr<MidiAction> + create(SharedPtr<Raul::Maid> maid, + size_t size, const unsigned char* event) + { + SharedPtr<MidiAction> ret(new MidiAction(size, event)); + maid->manage(ret); + return ret; + } + + static void set_driver(SharedPtr<MidiDriver> driver); bool set_event(size_t size, const byte* event); void execute(Timestamp time); private: - WeakPtr<MidiDriver> _driver; + 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/Node.hpp b/src/engine/machina/Node.hpp index d0e19db..243773f 100644 --- a/src/engine/machina/Node.hpp +++ b/src/engine/machina/Node.hpp @@ -43,11 +43,11 @@ public: Node(FrameCount duration=0, bool initial=false); - void add_enter_action(Action* action); - void remove_enter_action(Action* action); + void add_enter_action(SharedPtr<Action> action); + void remove_enter_action(SharedPtr<Action> action); - void add_exit_action(Action* action); - void remove_exit_action(Action* action); + void add_exit_action(SharedPtr<Action> action); + void remove_exit_action(SharedPtr<Action> action); void enter(Timestamp time); void exit(Timestamp time); @@ -67,13 +67,13 @@ public: const EdgeList& outgoing_edges() const { return _outgoing_edges; } private: - bool _is_initial; - bool _is_active; - Timestamp _enter_time; ///< valid iff _is_active - FrameCount _duration; - Action* _enter_action; - Action* _exit_action; - EdgeList _outgoing_edges; + bool _is_initial; + bool _is_active; + Timestamp _enter_time; ///< valid iff _is_active + FrameCount _duration; + SharedPtr<Action> _enter_action; + SharedPtr<Action> _exit_action; + EdgeList _outgoing_edges; }; diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp index 775ae28..d725253 100644 --- a/src/gui/MachinaCanvas.cpp +++ b/src/gui/MachinaCanvas.cpp @@ -21,6 +21,7 @@ #include "machina/Machine.hpp" #include "machina/Action.hpp" #include "machina/Edge.hpp" +#include "machina/LearnRequest.hpp" #include "NodeView.hpp" #include "MachinaCanvas.hpp" #include "MachinaGUI.hpp" @@ -47,15 +48,21 @@ void MachinaCanvas::node_clicked(SharedPtr<NodeView> item, GdkEventButton* event) { cerr << "CLICKED: " << item->name() << endl; - + SharedPtr<NodeView> node = PtrCast<NodeView>(item); if (!node) return; + // Middle click, learn + if (event->button == 2) { + _app->machine()->learn(Machina::LearnRequest::create(_app->maid(), node->node())); + return; + } + SharedPtr<NodeView> last = _last_clicked.lock(); if (last) { - connect(last, node); + connect_node(last, node); _last_clicked.reset(); } else { _last_clicked = node; @@ -79,7 +86,7 @@ MachinaCanvas::canvas_event(GdkEvent* event) string name = string("Note")+(char)(last++ +'0'); SharedPtr<Machina::Node> node(new Machina::Node(1024*10, false)); - node->add_enter_action(new Machina::PrintAction(name)); + //node->add_enter_action(SharedPtr<Machina::Action>(new Machina::PrintAction(name))); SharedPtr<NodeView> view(new NodeView(node, shared_from_this(), name, x, y)); @@ -100,8 +107,8 @@ MachinaCanvas::canvas_event(GdkEvent* event) void -MachinaCanvas::connect(boost::shared_ptr<NodeView> src, - boost::shared_ptr<NodeView> dst) +MachinaCanvas::connect_node(boost::shared_ptr<NodeView> src, + boost::shared_ptr<NodeView> dst) { boost::shared_ptr<Connection> c(new Connection(shared_from_this(), src, dst, 0x9999AAFF, true)); @@ -115,8 +122,8 @@ MachinaCanvas::connect(boost::shared_ptr<NodeView> src, void -MachinaCanvas::disconnect(boost::shared_ptr<NodeView>,// item1, - boost::shared_ptr<NodeView>)// item2) +MachinaCanvas::disconnect_node(boost::shared_ptr<NodeView>,// item1, + boost::shared_ptr<NodeView>)// item2) { #if 0 boost::shared_ptr<MachinaPort> input diff --git a/src/gui/MachinaCanvas.hpp b/src/gui/MachinaCanvas.hpp index 6cd5ea0..361e154 100644 --- a/src/gui/MachinaCanvas.hpp +++ b/src/gui/MachinaCanvas.hpp @@ -34,11 +34,11 @@ class MachinaCanvas : public FlowCanvas public: MachinaCanvas(MachinaGUI* app, int width, int height); - void connect(SharedPtr<NodeView> port1, - SharedPtr<NodeView> port2); + void connect_node(SharedPtr<NodeView> port1, + SharedPtr<NodeView> port2); - void disconnect(SharedPtr<NodeView> port1, - SharedPtr<NodeView> port2); + void disconnect_node(SharedPtr<NodeView> port1, + SharedPtr<NodeView> port2); void status_message(const string& msg); diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp index 09a3649..f091e60 100644 --- a/src/gui/MachinaGUI.cpp +++ b/src/gui/MachinaGUI.cpp @@ -65,12 +65,13 @@ gtkmm_set_width_for_given_text (Gtk::Widget &w, const gchar *text, -MachinaGUI::MachinaGUI(SharedPtr<Machina::Machine> m/*int argc, char** argv*/) +MachinaGUI::MachinaGUI(SharedPtr<Machina::Machine> machine) : _pane_closed(false), _update_pane_position(true), _user_pane_position(0), _refresh(false), - _machine(m) + _machine(machine), + _maid(new Raul::Maid(32)) { /*_settings_filename = getenv("HOME"); _settings_filename += "/.machinarc";*/ @@ -154,8 +155,8 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Machine> m/*int argc, char** argv*/) _update_pane_position = true; _pane_closed = true; - // Idle callback, check if we need to refresh - Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::idle_callback), 100); + // Idle callback to drive the maid (collect garbage) + Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::idle_callback), 1000); // Faster idle callback to update DSP load progress bar //Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::update_load), 50); @@ -185,34 +186,7 @@ MachinaGUI::attach() bool MachinaGUI::idle_callback() { -#if 0 - if (_jack_driver) { - while (!_jack_driver->events().empty()) { - MachinaEvent& ev = _jack_driver->events().front(); - _jack_driver->events().pop(); - ev.execute(); - } - } - - - bool refresh = _refresh; - - refresh = refresh || (_jack_driver && _jack_driver->is_dirty()); - - if (refresh) { - - _canvas->flag_all_connections(); - - _jack_driver->refresh(); - } - - if (refresh) { - _canvas->destroy_all_flagged_connections(); - _refresh = false; - } - - update_load(); -#endif + _maid->cleanup(); return true; } diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp index 4bcca5a..23b9dba 100644 --- a/src/gui/MachinaGUI.hpp +++ b/src/gui/MachinaGUI.hpp @@ -21,6 +21,7 @@ //#include "config.h" #include <string> #include <raul/SharedPtr.h> +#include <raul/Maid.h> #include <libgnomecanvasmm.h> using namespace std; @@ -32,12 +33,14 @@ class MachinaCanvas; class MachinaGUI { public: - MachinaGUI(SharedPtr<Machina::Machine> machine/*int argc, char** argv*/); + MachinaGUI(SharedPtr<Machina::Machine> machine); ~MachinaGUI(); boost::shared_ptr<MachinaCanvas> canvas() { return _canvas; } boost::shared_ptr<Machina::Machine> machine() { return _machine; } + SharedPtr<Raul::Maid> maid() { return _maid; } + Gtk::Window* window() { return _main_window; } void attach(); @@ -71,6 +74,8 @@ protected: boost::shared_ptr<MachinaCanvas> _canvas; boost::shared_ptr<Machina::Machine> _machine; + + SharedPtr<Raul::Maid> _maid; Gtk::Main* _gtk_main; diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 4e55e58..364fe17 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -40,12 +40,13 @@ main(int argc, char** argv) SharedPtr<Machina::Machine> m(new Machine()); m->activate(); + + MidiAction::set_driver(driver); driver->set_machine(m); driver->attach("machina"); - // Launch GUI try { diff --git a/src/main.cpp b/src/main.cpp index e4dcbf2..d3a0e57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,7 @@ #include "machina/Loader.hpp" #include "machina/JackDriver.hpp" #include "machina/JackNodeFactory.hpp" +#include "machina/MidiAction.hpp" using namespace std; using namespace Machina; @@ -55,6 +56,8 @@ main(int argc, char** argv) SharedPtr<JackDriver> driver(new JackDriver()); SharedPtr<NodeFactory> factory(new JackNodeFactory(driver)); + MidiAction::set_driver(driver); + Loader l(factory); SharedPtr<Machine> m = l.load(argv[1]); @@ -75,24 +78,3 @@ main(int argc, char** argv) return 0; } - - /* - Machine m(1); - - Node* n1 = create_debug_node("1", 1); - Node* n2 = create_debug_node("2", 10); - - m.initial_node()->add_outgoing_edge(new Edge(n1)); - n1->add_outgoing_edge(new Edge(n2)); - n2->add_outgoing_edge(new Edge(m.initial_node())); - */ - - /* - Timestamp t = 0; - - while (t < 4000) { - m->run(1000); - t += 1000; - } - */ - |