From 9f2a520a8f20661385bf6c9f7447aef1227d8696 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 10 Feb 2007 01:44:16 +0000 Subject: Fix previous (broken) commit. git-svn-id: http://svn.drobilla.net/lad/machina@296 a436a847-0d15-0410-975c-d299462d15a1 --- src/Action.hpp | 48 ------- src/Driver.hpp | 42 ------- src/Edge.hpp | 51 -------- src/JackActions.hpp | 57 --------- src/JackDriver.hpp | 60 --------- src/JackNodeFactory.hpp | 43 ------- src/Loader.hpp | 49 -------- src/Machina.hpp | 28 ----- src/Machine.hpp | 64 ---------- src/Node.hpp | 82 ------------ src/NodeFactory.hpp | 40 ------ src/engine/JackActions.cpp | 88 +++++++++++++ src/engine/JackDriver.cpp | 102 +++++++++++++++ src/engine/JackNodeFactory.cpp | 42 +++++++ src/engine/Loader.cpp | 221 ++++++++++++++++++++++++++++++++ src/engine/Machine.cpp | 224 +++++++++++++++++++++++++++++++++ src/engine/Makefile.am | 17 +++ src/engine/Node.cpp | 104 +++++++++++++++ src/engine/machina/Action.hpp | 48 +++++++ src/engine/machina/Driver.hpp | 42 +++++++ src/engine/machina/Edge.hpp | 51 ++++++++ src/engine/machina/JackActions.hpp | 57 +++++++++ src/engine/machina/JackDriver.hpp | 60 +++++++++ src/engine/machina/JackNodeFactory.hpp | 43 +++++++ src/engine/machina/Loader.hpp | 49 ++++++++ src/engine/machina/Machina.hpp | 28 +++++ src/engine/machina/Machine.hpp | 64 ++++++++++ src/engine/machina/Makefile.am | 12 ++ src/engine/machina/Node.hpp | 82 ++++++++++++ src/engine/machina/NodeFactory.hpp | 40 ++++++ src/engine/machina/types.hpp | 31 +++++ src/types.hpp | 31 ----- 32 files changed, 1405 insertions(+), 595 deletions(-) delete mode 100644 src/Action.hpp delete mode 100644 src/Driver.hpp delete mode 100644 src/Edge.hpp delete mode 100644 src/JackActions.hpp delete mode 100644 src/JackDriver.hpp delete mode 100644 src/JackNodeFactory.hpp delete mode 100644 src/Loader.hpp delete mode 100644 src/Machina.hpp delete mode 100644 src/Machine.hpp delete mode 100644 src/Node.hpp delete mode 100644 src/NodeFactory.hpp create mode 100644 src/engine/JackActions.cpp create mode 100644 src/engine/JackDriver.cpp create mode 100644 src/engine/JackNodeFactory.cpp create mode 100644 src/engine/Loader.cpp create mode 100644 src/engine/Machine.cpp create mode 100644 src/engine/Makefile.am create mode 100644 src/engine/Node.cpp create mode 100644 src/engine/machina/Action.hpp create mode 100644 src/engine/machina/Driver.hpp create mode 100644 src/engine/machina/Edge.hpp create mode 100644 src/engine/machina/JackActions.hpp create mode 100644 src/engine/machina/JackDriver.hpp create mode 100644 src/engine/machina/JackNodeFactory.hpp create mode 100644 src/engine/machina/Loader.hpp create mode 100644 src/engine/machina/Machina.hpp create mode 100644 src/engine/machina/Machine.hpp create mode 100644 src/engine/machina/Makefile.am create mode 100644 src/engine/machina/Node.hpp create mode 100644 src/engine/machina/NodeFactory.hpp create mode 100644 src/engine/machina/types.hpp delete mode 100644 src/types.hpp diff --git a/src/Action.hpp b/src/Action.hpp deleted file mode 100644 index ffee5b1..0000000 --- a/src/Action.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef MACHINA_ACTION_HPP -#define MACHINA_ACTION_HPP - -#include -#include -#include "types.hpp" - -namespace Machina { - - -struct Action { - virtual ~Action() {} - - virtual void execute(Timestamp /*time*/) {} -}; - - -class PrintAction : public Action { -public: - PrintAction(const std::string& msg) : _msg(msg) {} - - void execute(Timestamp time) { std::cout << "t=" << time << ": " << _msg << std::endl; } - -private: - std::string _msg; -}; - - -} // namespace Machina - -#endif // MACHINA_ACTION_HPP diff --git a/src/Driver.hpp b/src/Driver.hpp deleted file mode 100644 index f2816ba..0000000 --- a/src/Driver.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_JACKDRIVER_HPP -#define MACHINA_JACKDRIVER_HPP - -#include - -namespace Machine { - - -class JackDriver : public Raul::JackDriver { -public: - JackDriver(SharedPtr machine); - - virtual void set_machine(SharedPtr machine); - -protected: - virtual void on_process(jack_nframes_t nframes); - -private: - SharedPtr _machine; -}; - - -} // namespace Machina - -#endif // MACHINA_JACKDRIVER_HPP diff --git a/src/Edge.hpp b/src/Edge.hpp deleted file mode 100644 index f20e5db..0000000 --- a/src/Edge.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef MACHINA_EDGE_HPP -#define MACHINA_EDGE_HPP - -#include -#include -#include -#include -#include "types.hpp" -#include "Action.hpp" - -namespace Machina { - -class Node; - -class Edge : boost::noncopyable { -public: - - Edge(WeakPtr src, SharedPtr dst) : _src(src) , _dst(dst) {} - - WeakPtr src() { return _src; } - SharedPtr dst() { return _dst; } - - void set_src(WeakPtr src) { _src = src; } - void set_dst(SharedPtr dst) { _dst = dst; } - -private: - WeakPtr _src; - SharedPtr _dst; -}; - - -} // namespace Machina - -#endif // MACHINA_EDGE_HPP diff --git a/src/JackActions.hpp b/src/JackActions.hpp deleted file mode 100644 index 0eb50b8..0000000 --- a/src/JackActions.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_JACKACTIONS_HPP -#define MACHINA_JACKACTIONS_HPP - -#include -#include "types.hpp" -#include "Action.hpp" - -namespace Machina { - -class Node; -class JackDriver; - - -class JackNoteOnAction : public Action { -public: - JackNoteOnAction(WeakPtr driver, unsigned char note_num); - - void execute(Timestamp time); - -private: - WeakPtr _driver; - unsigned char _note_num; -}; - - -class JackNoteOffAction : public Action { -public: - JackNoteOffAction(WeakPtr driver, unsigned char note_num); - - void execute(Timestamp time); - -private: - WeakPtr _driver; - unsigned char _note_num; -}; - - -} // namespace Machina - -#endif // MACHINA_JACKACTIONS_HPP diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp deleted file mode 100644 index 84c9223..0000000 --- a/src/JackDriver.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_JACKDRIVER_HPP -#define MACHINA_JACKDRIVER_HPP - -#include -#include -#include -#include "Machine.hpp" - -namespace Machina { - - -class JackDriver : public Raul::JackDriver { -public: - JackDriver(); - - void attach(const std::string& client_name); - void detach(); - - void set_machine(SharedPtr machine) { _machine = machine; } - - // Audio context - Timestamp stamp_to_offset(Timestamp stamp); - jack_port_t* output_port() { return _output_port; } - //Timestamp current_cycle_start() { return _current_cycle_start; } - //Timestamp current_cycle_offset() { return _current_cycle_offset; } - FrameCount current_cycle_nframes() { return _current_cycle_nframes; } - - -protected: - virtual void on_process(jack_nframes_t nframes); - -private: - SharedPtr _machine; - jack_port_t* _output_port; - Timestamp _current_cycle_start; - Timestamp _current_cycle_offset; ///< for split cycles - FrameCount _current_cycle_nframes; -}; - - -} // namespace Machina - -#endif // MACHINA_JACKDRIVER_HPP diff --git a/src/JackNodeFactory.hpp b/src/JackNodeFactory.hpp deleted file mode 100644 index 017cc6d..0000000 --- a/src/JackNodeFactory.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_JACKNODEFACTORY_HPP -#define MACHINA_JACKNODEFACTORY_HPP - -#include -#include "NodeFactory.hpp" - -namespace Machina { - -class JackDriver; - - -class JackNodeFactory : public NodeFactory { -public: - JackNodeFactory(WeakPtr driver) : _driver(driver) {} - - SharedPtr create_node(Node::ID id, - unsigned char note, - FrameCount duration); -private: - WeakPtr _driver; -}; - - -} // namespace Machina - -#endif // MACHINA_JACKNODEFACTORY_HPP diff --git a/src/Loader.hpp b/src/Loader.hpp deleted file mode 100644 index c3ce013..0000000 --- a/src/Loader.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_LOADER_HPP -#define MACHINA_LOADER_HPP - -#include -#include "raul/SharedPtr.h" -#include "raul/Path.h" -#include "raul/Namespaces.h" - -using Raul::Namespaces; - -namespace Machina { - -class Machine; -class NodeFactory; - - -class Loader { -public: - Loader(SharedPtr node_factory, - SharedPtr = SharedPtr()); - - SharedPtr load(const Glib::ustring& filename); - -private: - SharedPtr _node_factory; - SharedPtr _namespaces; -}; - - -} // namespace Machina - -#endif // MACHINA_LOADER_HPP diff --git a/src/Machina.hpp b/src/Machina.hpp deleted file mode 100644 index 6cefcc5..0000000 --- a/src/Machina.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -namespace Machina { - -class Machina { -private: - std::list _nodes; -}; - - -} // namespace Machina diff --git a/src/Machine.hpp b/src/Machine.hpp deleted file mode 100644 index 2ac739e..0000000 --- a/src/Machine.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef MACHINA_MACHINE_HPP -#define MACHINA_MACHINE_HPP - -#include -#include -#include "raul/SharedPtr.h" -#include "types.hpp" -#include "Node.hpp" - -namespace Machina { - - -class Machine { -public: - Machine(); - ~Machine(); - - // Main context - void activate() { _is_activated = true; } - void deactivate() { _is_activated = false; } - - void add_node(SharedPtr node); - - // Audio context - void reset(); - bool run(FrameCount nframes); - - // Any context - FrameCount time() { return _time; } - -private: - typedef std::vector > Nodes; - - // Audio context - SharedPtr earliest_node() const; - void exit_node(const SharedPtr); - - bool _is_activated; - bool _is_finished; - FrameCount _time; - Nodes _nodes; -}; - - -} // namespace Machina - -#endif // MACHINA_MACHINE_HPP diff --git a/src/Node.hpp b/src/Node.hpp deleted file mode 100644 index 1e09646..0000000 --- a/src/Node.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef MACHINA_NODE_HPP -#define MACHINA_NODE_HPP - -#include -#include -#include -#include "types.hpp" -#include "Action.hpp" - -namespace Machina { - -class Edge; - - -/** A node is a state (as in a FSM diagram), or "note". - * - * It contains a action, as well as a duration and pointers to it's - * successors (states/nodes that (may) follow it). - * - * Initial nodes do not have enter actions (since they are entered at - * an undefined point in time <= 0). - */ -class Node : public boost::noncopyable { -public: - typedef std::string ID; - - Node(FrameCount duration=0, bool initial=false); - - void add_enter_action(Action* action); - void remove_enter_action(Action* action); - - void add_exit_action(Action* action); - void remove_exit_action(Action* action); - - void enter(Timestamp time); - void exit(Timestamp time); - - void add_outgoing_edge(SharedPtr edge); - void remove_outgoing_edge(SharedPtr edge); - - bool is_initial() const { return _is_initial; } - void set_initial(bool i) { _is_initial = i; } - bool is_active() const { return _is_active; } - Timestamp enter_time() const { return _enter_time; } - Timestamp exit_time() const { return _enter_time + _duration; } - FrameCount duration() { return _duration; } - void set_duration(FrameCount d) { _duration = d; } - - typedef std::list > EdgeList; - 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; -}; - - -} // namespace Machina - -#endif // MACHINA_NODE_HPP diff --git a/src/NodeFactory.hpp b/src/NodeFactory.hpp deleted file mode 100644 index f38fd92..0000000 --- a/src/NodeFactory.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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_NODEFACTORY_HPP -#define MACHINA_NODEFACTORY_HPP - -#include -#include "types.hpp" -#include "Node.hpp" - -namespace Machina { - - -class NodeFactory { -public: - virtual ~NodeFactory() {} - - virtual SharedPtr create_node(Node::ID id, - unsigned char note, - FrameCount duration) = 0; -}; - - -} // namespace Machina - -#endif // MACHINA_NODEFACTORY_HPP diff --git a/src/engine/JackActions.cpp b/src/engine/JackActions.cpp new file mode 100644 index 0000000..b55e493 --- /dev/null +++ b/src/engine/JackActions.cpp @@ -0,0 +1,88 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 + */ + +#include +#include "machina/JackActions.hpp" +#include "machina/JackDriver.hpp" + +namespace Machina { + + +/* NOTE ON */ + +JackNoteOnAction::JackNoteOnAction(WeakPtr driver, + unsigned char note_num) + : _driver(driver) + , _note_num(note_num) +{ +} + + +void +JackNoteOnAction::execute(Timestamp time) +{ + SharedPtr driver = _driver.lock(); + if (!driver) + return; + + const FrameCount nframes = driver->current_cycle_nframes(); + const FrameCount offset = driver->stamp_to_offset(time); + + //std::cerr << offset << " \tNOTE ON:\t" << (int)_note_num << "\t@ " << time << std::endl; + + jack_midi_data_t ev[] = { 0x80, _note_num, 0x40 }; + + jack_midi_event_write( + jack_port_get_buffer(driver->output_port(), nframes), + offset, ev, 3, nframes); +} + + + +/* NOTE OFF */ + +JackNoteOffAction::JackNoteOffAction(WeakPtr driver, + unsigned char note_num) + : _driver(driver) + , _note_num(note_num) +{ +} + + +void +JackNoteOffAction::execute(Timestamp time) +{ + SharedPtr driver = _driver.lock(); + if (!driver) + return; + + const FrameCount nframes = driver->current_cycle_nframes(); + const FrameCount offset = driver->stamp_to_offset(time); + + //std::cerr << offset << " \tNOTE OFF:\t" << (int)_note_num << "\t@ " << time << std::endl; + + jack_midi_data_t ev[] = { 0x90, _note_num, 0x40 }; + + jack_midi_event_write( + jack_port_get_buffer(driver->output_port(), nframes), + offset, ev, 3, nframes); +} + + +} // namespace Machina + + diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp new file mode 100644 index 0000000..848c3d7 --- /dev/null +++ b/src/engine/JackDriver.cpp @@ -0,0 +1,102 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 + */ + +#include "machina/JackDriver.hpp" + +#include + +namespace Machina { + + +JackDriver::JackDriver() + : _output_port(NULL) + , _current_cycle_start(0) + , _current_cycle_nframes(0) +{ +} + + +void +JackDriver::attach(const std::string& client_name) +{ + Raul::JackDriver::attach(client_name); + + if (jack_client()) { + _output_port = jack_port_register(jack_client(), + "out", + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, + 0); + } +} + + +void +JackDriver::detach() +{ + jack_port_unregister(jack_client(), _output_port); + _output_port = NULL; + + Raul::JackDriver::detach(); +} + + +Timestamp +JackDriver::stamp_to_offset(Timestamp stamp) +{ + Timestamp ret = stamp - _current_cycle_start + _current_cycle_offset; + assert(ret < _current_cycle_offset + _current_cycle_nframes); + return ret; +} + + +void +JackDriver::on_process(jack_nframes_t nframes) +{ + //std::cerr << "======================================================\n"; + + _current_cycle_offset = 0; + _current_cycle_nframes = nframes; + + jack_midi_clear_buffer(jack_port_get_buffer(_output_port, nframes), nframes); + + while (true) { + + bool machine_done = ! _machine->run(_current_cycle_nframes); + + if (!machine_done) { + _current_cycle_start += _current_cycle_nframes; + break; + + } else { + const Timestamp finish_time = _machine->time(); + const FrameCount finish_offset = stamp_to_offset(finish_time); + + if (finish_offset >= _current_cycle_nframes) + break; + + _current_cycle_offset = stamp_to_offset(finish_time); + _current_cycle_nframes -= _current_cycle_offset; + _current_cycle_start = 0; + _machine->reset(); + } + } + + //std::cerr << "======================================================\n"; +} + + +} // namespace Machina diff --git a/src/engine/JackNodeFactory.cpp b/src/engine/JackNodeFactory.cpp new file mode 100644 index 0000000..09670e1 --- /dev/null +++ b/src/engine/JackNodeFactory.cpp @@ -0,0 +1,42 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 + */ + +#include "machina/JackNodeFactory.hpp" +#include "machina/JackActions.hpp" +#include "machina/Node.hpp" + +namespace Machina { + + +SharedPtr +JackNodeFactory::create_node(Node::ID, unsigned char note, FrameCount duration) +{ + // FIXME: leaks like a sieve, obviously + + Node* n = new Node(duration); + JackNoteOnAction* a_enter = new JackNoteOnAction(_driver, note); + JackNoteOffAction* a_exit = new JackNoteOffAction(_driver, note); + + n->add_enter_action(a_enter); + n->add_exit_action(a_exit); + + return SharedPtr(n); +} + + +} // namespace Machina + diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp new file mode 100644 index 0000000..3b58537 --- /dev/null +++ b/src/engine/Loader.cpp @@ -0,0 +1,221 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include "machina/Loader.hpp" +#include "machina/Node.hpp" +#include "machina/Edge.hpp" +#include "machina/Machine.hpp" +#include "machina/NodeFactory.hpp" + +using namespace Raul; +using std::cerr; using std::cout; using std::endl; + +namespace Machina { + + +/* +// FIXME: remove +Node* create_debug_node(const Node::ID& id, FrameCount duration) +{ + // leaks like a sieve, obviously + + Node* n = new Node(duration); + PrintAction* a_enter = new PrintAction(string("\t> ") + id); + PrintAction* a_exit = new PrintAction(string("\t< ") + id); + + n->add_enter_action(a_enter); + n->add_exit_action(a_exit); + + cerr << "dur: " << duration << endl; + + return n; +} +*/ + +Loader::Loader(SharedPtr node_factory, + SharedPtr namespaces) + : _node_factory(node_factory) + , _namespaces(namespaces) +{ + if (!_namespaces) + _namespaces = SharedPtr(new Namespaces()); + + (*_namespaces)[""] = "http://drobilla.net/ns/machina#"; + (*_namespaces)["xsd"] = "http://www.w3.org/2001/XMLSchema#"; +} + + +/** Load (create) all objects from an RDF into the engine. + * + * @param filename Filename to load objects from. + * @param parent Path of parent under which to load objects. + * @return whether or not load was successful. + */ +SharedPtr +Loader::load(const Glib::ustring& filename) +{ + using Raul::RDFQuery; + SharedPtr machine; + + rasqal_init(); + + unsigned char* document_uri_str = raptor_uri_filename_to_uri_string(filename.c_str()); + assert(document_uri_str); + raptor_uri* document_raptor_uri = raptor_new_uri(document_uri_str); + + if (!document_uri_str) + return machine; + + machine = SharedPtr(new Machine()); + + Glib::ustring document_uri = (const char*)document_uri_str; + + string machine_uri = "<> "; + + cout << "[Loader] Loading " << machine_uri << " from " << document_uri << endl; + + typedef std::map > Created; + Created created; + + + /* Get initial nodes */ + + Raul::RDFQuery query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?initialNode ?midiNote ?duration FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :initialNode ?initialNode .\n" + "?initialNode :midiNote ?midiNote ;\n" + " :duration ?duration .\n" + "}\n"); + + RDFQuery::Results results = query.run(document_uri); + + for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { + const Glib::ustring& node_uri = (*i)["initialNode"]; + const Glib::ustring& midi_note = (*i)["midiNote"]; + const Glib::ustring& duration = (*i)["duration"]; + + raptor_uri* node_raptor_uri + = raptor_new_uri((const unsigned char*)node_uri.c_str()); + + char* node_name = (char*) + raptor_uri_to_relative_uri_string(document_raptor_uri, node_raptor_uri); + + //cout << "Initial: " << node_name << ": " << midi_note << " - " << duration << endl; + + SharedPtr node = SharedPtr(_node_factory->create_node( + node_name, + strtol(midi_note.c_str(), NULL, 10), + strtol(duration.c_str(), NULL, 10))); + + node->set_initial(true); + //machine->add_node(string(node_name).substr(1), node); // (chop leading "#") + machine->add_node(node); + + created.insert(std::make_pair(node_uri.collate_key(), node)); + + raptor_free_uri(node_raptor_uri); + free(node_name); + } + + + /* Get remaining nodes */ + + query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?node ?midiNote ?duration FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :node ?node .\n" + "?node :midiNote ?midiNote ;\n" + " :duration ?duration .\n" + "}\n"); + + results = query.run(document_uri); + + for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { + const Glib::ustring& node_uri = (*i)["node"]; + const Glib::ustring& midi_note = (*i)["midiNote"]; + const Glib::ustring& duration = (*i)["duration"]; + + raptor_uri* node_raptor_uri + = raptor_new_uri((const unsigned char*)node_uri.c_str()); + + char* node_name = (char*) + raptor_uri_to_relative_uri_string(document_raptor_uri, node_raptor_uri); + + + SharedPtr node = SharedPtr(_node_factory->create_node( + node_name, + strtol(midi_note.c_str(), NULL, 10), + strtol(duration.c_str(), NULL, 10))); + + if (created.find(node_uri) == created.end()) { + //cout << "Node: " << node_name << ": " << midi_note << " - " << duration << endl; + //machine->add_node(string(node_name).substr(1), node); // (chop leading "#") + machine->add_node(node); + created.insert(std::make_pair(node_uri.collate_key(), node)); + } + + raptor_free_uri(node_raptor_uri); + free(node_name); + } + + + /* Get edges */ + + query = Raul::RDFQuery(*_namespaces, Glib::ustring( + "SELECT DISTINCT ?src ?edge ?dst FROM <") + + document_uri + "> WHERE {\n" + + machine_uri + " :edge ?edge .\n" + "?edge :tail ?src ;\n" + " :head ?dst .\n }"); + results = query.run(document_uri); + + for (RDFQuery::Results::iterator i = results.begin(); i != results.end(); ++i) { + const Glib::ustring& src_uri = (*i)["src"]; + const Glib::ustring& dst_uri = (*i)["dst"]; + + Created::iterator src_i = created.find(src_uri.collate_key()); + Created::iterator dst_i = created.find(dst_uri.collate_key()); + + if (src_i != created.end() && dst_i != created.end()) { + const SharedPtr src = src_i->second; + const SharedPtr dst = dst_i->second; + + src->add_outgoing_edge(SharedPtr(new Edge(src, dst))); + + } else { + cerr << "[Loader] WARNING: Ignored edge between unknown nodes " + << src_uri << " -> " << dst_uri << endl; + } + + } + + free(document_uri_str); + raptor_free_uri(document_raptor_uri); + + return machine; +} + + +} // namespace Machina + diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp new file mode 100644 index 0000000..426ffd3 --- /dev/null +++ b/src/engine/Machine.cpp @@ -0,0 +1,224 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "machina/Machine.hpp" +#include "machina/Node.hpp" +#include "machina/Edge.hpp" + +namespace Machina { + + +Machine::Machine() + : _is_activated(false) + , _is_finished(false) + , _time(0) +{ +} + + +Machine::~Machine() +{ +} + + +void +Machine::add_node(SharedPtr node) +{ + assert(!_is_activated); + + _nodes.push_back(node); +} + + +/** Exit all active states and reset time to 0. + */ +void +Machine::reset() +{ + if (!_is_finished) { + for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { + const SharedPtr node = (*n); + + if (node->is_active()) + node->exit(_time); + } + } + + _time = 0; + _is_finished = false; +} + + +/** Return the active Node with the earliest exit time. + */ +SharedPtr +Machine::earliest_node() const +{ + SharedPtr earliest; + + for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { + const SharedPtr node = (*n); + + if (node->is_active()) + if (!earliest || node->exit_time() < earliest->exit_time()) + earliest = node; + } + + return earliest; +} + + +/** Exit an active node at the current _time. + */ +void +Machine::exit_node(const SharedPtr node) +{ + node->exit(_time); + + // Activate all successors to this node + // (that aren't aready active right now) + for (Node::EdgeList::const_iterator s = node->outgoing_edges().begin(); + s != node->outgoing_edges().end(); ++s) { + SharedPtr dst = (*s)->dst(); + + if (!dst->is_active()) + dst->enter(_time); + + } +} + + +/** 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 + * machine actually finished on (so it can be restarted immediately + * with sample accuracy if necessary). + */ +bool +Machine::run(FrameCount nframes) +{ + if (_is_finished) + return false; + + if (_nodes.size() == 0) + return true; + + const FrameCount cycle_end = _time + nframes; + + assert(_is_activated); + + //std::cerr << "--------- " << _time << " - " << _time + nframes << std::endl; + + // Initial run, enter all initial states + if (_time == 0) + for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) + if ((*n)->is_initial()) + (*n)->enter(0); + + while (true) { + + SharedPtr earliest = earliest_node(); + + // No more active states, machine is finished + if (!earliest) { + _is_finished = true; + return false; + + // Earliest active state ends this cycle + } else if (earliest->exit_time() < cycle_end) { + _time = earliest->exit_time(); + exit_node(earliest); + + // Earliest active state ends in the future, done this cycle + } else { + _time = cycle_end; + return true; + } + + } + +#if 0 + while (!done) { + + done = true; + + for (std::vector::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; + } + } + + latest_event = end_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::iterator i = _voices.begin(); + i != _voices.end(); ++i) + if ((*i) != NULL && (*i)->is_active()) + is_reset = false; + + // ... then start + if (is_reset) { + + std::vector::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; + + return false; +#endif +} + + +} // namespace Machina + diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am new file mode 100644 index 0000000..2e0c363 --- /dev/null +++ b/src/engine/Makefile.am @@ -0,0 +1,17 @@ +SUBDIRS = machina + +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 \ + Machine.cpp \ + Loader.h \ + Loader.cpp \ + JackDriver.h \ + JackDriver.cpp \ + JackActions.cpp \ + JackNodeFactory.cpp diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp new file mode 100644 index 0000000..def7a70 --- /dev/null +++ b/src/engine/Node.cpp @@ -0,0 +1,104 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "machina/Node.hpp" +#include "machina/Edge.hpp" + +namespace Machina { + + +Node::Node(FrameCount duration, bool initial) + : _is_initial(initial) + , _is_active(false) + , _enter_time(0) + , _duration(duration) + , _enter_action(NULL) + , _exit_action(NULL) +{ +} + + +void +Node::add_enter_action(Action* action) +{ + assert(!_enter_action); + _enter_action = action; +} + + +void +Node::remove_enter_action(Action* /*action*/) +{ + _enter_action = NULL; +} + + + +void +Node::add_exit_action(Action* action) +{ + assert(!_exit_action); + _exit_action = action; +} + + +void +Node::remove_exit_action(Action* /*action*/) +{ + _exit_action = NULL; +} + + +void +Node::enter(Timestamp time) +{ + _is_active = true; + _enter_time = time; + if (_enter_action) + _enter_action->execute(time); +} + + +void +Node::exit(Timestamp time) +{ + if (_exit_action) + _exit_action->execute(time); + _is_active = false; + _enter_time = 0; +} + + +void +Node::add_outgoing_edge(SharedPtr edge) +{ + assert(edge->src().lock().get() == this); + + _outgoing_edges.push_back(edge); +} + + +void +Node::remove_outgoing_edge(SharedPtr edge) +{ + _outgoing_edges.erase(_outgoing_edges.find(edge)); +} + + +} // namespace Machina + diff --git a/src/engine/machina/Action.hpp b/src/engine/machina/Action.hpp new file mode 100644 index 0000000..ffee5b1 --- /dev/null +++ b/src/engine/machina/Action.hpp @@ -0,0 +1,48 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MACHINA_ACTION_HPP +#define MACHINA_ACTION_HPP + +#include +#include +#include "types.hpp" + +namespace Machina { + + +struct Action { + virtual ~Action() {} + + virtual void execute(Timestamp /*time*/) {} +}; + + +class PrintAction : public Action { +public: + PrintAction(const std::string& msg) : _msg(msg) {} + + void execute(Timestamp time) { std::cout << "t=" << time << ": " << _msg << std::endl; } + +private: + std::string _msg; +}; + + +} // namespace Machina + +#endif // MACHINA_ACTION_HPP diff --git a/src/engine/machina/Driver.hpp b/src/engine/machina/Driver.hpp new file mode 100644 index 0000000..f2816ba --- /dev/null +++ b/src/engine/machina/Driver.hpp @@ -0,0 +1,42 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_JACKDRIVER_HPP +#define MACHINA_JACKDRIVER_HPP + +#include + +namespace Machine { + + +class JackDriver : public Raul::JackDriver { +public: + JackDriver(SharedPtr machine); + + virtual void set_machine(SharedPtr machine); + +protected: + virtual void on_process(jack_nframes_t nframes); + +private: + SharedPtr _machine; +}; + + +} // namespace Machina + +#endif // MACHINA_JACKDRIVER_HPP diff --git a/src/engine/machina/Edge.hpp b/src/engine/machina/Edge.hpp new file mode 100644 index 0000000..f20e5db --- /dev/null +++ b/src/engine/machina/Edge.hpp @@ -0,0 +1,51 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MACHINA_EDGE_HPP +#define MACHINA_EDGE_HPP + +#include +#include +#include +#include +#include "types.hpp" +#include "Action.hpp" + +namespace Machina { + +class Node; + +class Edge : boost::noncopyable { +public: + + Edge(WeakPtr src, SharedPtr dst) : _src(src) , _dst(dst) {} + + WeakPtr src() { return _src; } + SharedPtr dst() { return _dst; } + + void set_src(WeakPtr src) { _src = src; } + void set_dst(SharedPtr dst) { _dst = dst; } + +private: + WeakPtr _src; + SharedPtr _dst; +}; + + +} // namespace Machina + +#endif // MACHINA_EDGE_HPP diff --git a/src/engine/machina/JackActions.hpp b/src/engine/machina/JackActions.hpp new file mode 100644 index 0000000..0eb50b8 --- /dev/null +++ b/src/engine/machina/JackActions.hpp @@ -0,0 +1,57 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_JACKACTIONS_HPP +#define MACHINA_JACKACTIONS_HPP + +#include +#include "types.hpp" +#include "Action.hpp" + +namespace Machina { + +class Node; +class JackDriver; + + +class JackNoteOnAction : public Action { +public: + JackNoteOnAction(WeakPtr driver, unsigned char note_num); + + void execute(Timestamp time); + +private: + WeakPtr _driver; + unsigned char _note_num; +}; + + +class JackNoteOffAction : public Action { +public: + JackNoteOffAction(WeakPtr driver, unsigned char note_num); + + void execute(Timestamp time); + +private: + WeakPtr _driver; + unsigned char _note_num; +}; + + +} // namespace Machina + +#endif // MACHINA_JACKACTIONS_HPP diff --git a/src/engine/machina/JackDriver.hpp b/src/engine/machina/JackDriver.hpp new file mode 100644 index 0000000..84c9223 --- /dev/null +++ b/src/engine/machina/JackDriver.hpp @@ -0,0 +1,60 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_JACKDRIVER_HPP +#define MACHINA_JACKDRIVER_HPP + +#include +#include +#include +#include "Machine.hpp" + +namespace Machina { + + +class JackDriver : public Raul::JackDriver { +public: + JackDriver(); + + void attach(const std::string& client_name); + void detach(); + + void set_machine(SharedPtr machine) { _machine = machine; } + + // Audio context + Timestamp stamp_to_offset(Timestamp stamp); + jack_port_t* output_port() { return _output_port; } + //Timestamp current_cycle_start() { return _current_cycle_start; } + //Timestamp current_cycle_offset() { return _current_cycle_offset; } + FrameCount current_cycle_nframes() { return _current_cycle_nframes; } + + +protected: + virtual void on_process(jack_nframes_t nframes); + +private: + SharedPtr _machine; + jack_port_t* _output_port; + Timestamp _current_cycle_start; + Timestamp _current_cycle_offset; ///< for split cycles + FrameCount _current_cycle_nframes; +}; + + +} // namespace Machina + +#endif // MACHINA_JACKDRIVER_HPP diff --git a/src/engine/machina/JackNodeFactory.hpp b/src/engine/machina/JackNodeFactory.hpp new file mode 100644 index 0000000..017cc6d --- /dev/null +++ b/src/engine/machina/JackNodeFactory.hpp @@ -0,0 +1,43 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_JACKNODEFACTORY_HPP +#define MACHINA_JACKNODEFACTORY_HPP + +#include +#include "NodeFactory.hpp" + +namespace Machina { + +class JackDriver; + + +class JackNodeFactory : public NodeFactory { +public: + JackNodeFactory(WeakPtr driver) : _driver(driver) {} + + SharedPtr create_node(Node::ID id, + unsigned char note, + FrameCount duration); +private: + WeakPtr _driver; +}; + + +} // namespace Machina + +#endif // MACHINA_JACKNODEFACTORY_HPP diff --git a/src/engine/machina/Loader.hpp b/src/engine/machina/Loader.hpp new file mode 100644 index 0000000..c3ce013 --- /dev/null +++ b/src/engine/machina/Loader.hpp @@ -0,0 +1,49 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_LOADER_HPP +#define MACHINA_LOADER_HPP + +#include +#include "raul/SharedPtr.h" +#include "raul/Path.h" +#include "raul/Namespaces.h" + +using Raul::Namespaces; + +namespace Machina { + +class Machine; +class NodeFactory; + + +class Loader { +public: + Loader(SharedPtr node_factory, + SharedPtr = SharedPtr()); + + SharedPtr load(const Glib::ustring& filename); + +private: + SharedPtr _node_factory; + SharedPtr _namespaces; +}; + + +} // namespace Machina + +#endif // MACHINA_LOADER_HPP diff --git a/src/engine/machina/Machina.hpp b/src/engine/machina/Machina.hpp new file mode 100644 index 0000000..6cefcc5 --- /dev/null +++ b/src/engine/machina/Machina.hpp @@ -0,0 +1,28 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +namespace Machina { + +class Machina { +private: + std::list _nodes; +}; + + +} // namespace Machina diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp new file mode 100644 index 0000000..2ac739e --- /dev/null +++ b/src/engine/machina/Machine.hpp @@ -0,0 +1,64 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MACHINA_MACHINE_HPP +#define MACHINA_MACHINE_HPP + +#include +#include +#include "raul/SharedPtr.h" +#include "types.hpp" +#include "Node.hpp" + +namespace Machina { + + +class Machine { +public: + Machine(); + ~Machine(); + + // Main context + void activate() { _is_activated = true; } + void deactivate() { _is_activated = false; } + + void add_node(SharedPtr node); + + // Audio context + void reset(); + bool run(FrameCount nframes); + + // Any context + FrameCount time() { return _time; } + +private: + typedef std::vector > Nodes; + + // Audio context + SharedPtr earliest_node() const; + void exit_node(const SharedPtr); + + bool _is_activated; + bool _is_finished; + FrameCount _time; + Nodes _nodes; +}; + + +} // namespace Machina + +#endif // MACHINA_MACHINE_HPP diff --git a/src/engine/machina/Makefile.am b/src/engine/machina/Makefile.am new file mode 100644 index 0000000..eca6f9b --- /dev/null +++ b/src/engine/machina/Makefile.am @@ -0,0 +1,12 @@ +libmachinaincludedir = $(includedir)/machina + +libmachinainclude_HEADERS = \ + types.hpp \ + Node.hpp \ + Edge.hpp \ + Machine.hpp \ + Loader.hpp \ + JackDriver.hpp \ + JackActions.hpp \ + NodeFactory.hpp \ + JackNodeFactory.hpp diff --git a/src/engine/machina/Node.hpp b/src/engine/machina/Node.hpp new file mode 100644 index 0000000..d0e19db --- /dev/null +++ b/src/engine/machina/Node.hpp @@ -0,0 +1,82 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MACHINA_NODE_HPP +#define MACHINA_NODE_HPP + +#include +#include +#include +#include "types.hpp" +#include "Action.hpp" + +namespace Machina { + +class Edge; + + +/** A node is a state (as in a FSM diagram), or "note". + * + * It contains a action, as well as a duration and pointers to it's + * successors (states/nodes that (may) follow it). + * + * Initial nodes do not have enter actions (since they are entered at + * an undefined point in time <= 0). + */ +class Node : public boost::noncopyable { +public: + typedef std::string ID; + + Node(FrameCount duration=0, bool initial=false); + + void add_enter_action(Action* action); + void remove_enter_action(Action* action); + + void add_exit_action(Action* action); + void remove_exit_action(Action* action); + + void enter(Timestamp time); + void exit(Timestamp time); + + void add_outgoing_edge(SharedPtr edge); + void remove_outgoing_edge(SharedPtr edge); + + bool is_initial() const { return _is_initial; } + void set_initial(bool i) { _is_initial = i; } + bool is_active() const { return _is_active; } + Timestamp enter_time() const { return _enter_time; } + Timestamp exit_time() const { return _enter_time + _duration; } + FrameCount duration() { return _duration; } + void set_duration(FrameCount d) { _duration = d; } + + typedef Raul::List > EdgeList; + 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; +}; + + +} // namespace Machina + +#endif // MACHINA_NODE_HPP diff --git a/src/engine/machina/NodeFactory.hpp b/src/engine/machina/NodeFactory.hpp new file mode 100644 index 0000000..f38fd92 --- /dev/null +++ b/src/engine/machina/NodeFactory.hpp @@ -0,0 +1,40 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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_NODEFACTORY_HPP +#define MACHINA_NODEFACTORY_HPP + +#include +#include "types.hpp" +#include "Node.hpp" + +namespace Machina { + + +class NodeFactory { +public: + virtual ~NodeFactory() {} + + virtual SharedPtr create_node(Node::ID id, + unsigned char note, + FrameCount duration) = 0; +}; + + +} // namespace Machina + +#endif // MACHINA_NODEFACTORY_HPP diff --git a/src/engine/machina/types.hpp b/src/engine/machina/types.hpp new file mode 100644 index 0000000..8793fb1 --- /dev/null +++ b/src/engine/machina/types.hpp @@ -0,0 +1,31 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MACHINA_TYPES_HPP +#define MACHINA_TYPES_HPP + +#include + +namespace Machina { + + +typedef jack_nframes_t FrameCount; +typedef jack_nframes_t Timestamp; + +} // namespace Machina + +#endif // MACHINA_TYPES_HPP diff --git a/src/types.hpp b/src/types.hpp deleted file mode 100644 index 8793fb1..0000000 --- a/src/types.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007 Dave Robillard - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef MACHINA_TYPES_HPP -#define MACHINA_TYPES_HPP - -#include - -namespace Machina { - - -typedef jack_nframes_t FrameCount; -typedef jack_nframes_t Timestamp; - -} // namespace Machina - -#endif // MACHINA_TYPES_HPP -- cgit v1.2.1