From f293da6bc4f0f631c086d35666e3e8bfef19b8f2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 10 Jan 2011 21:23:14 +0000 Subject: Rewrite with UI/engine split. Note some things aren't quite working right again yet... git-svn-id: http://svn.drobilla.net/lad/trunk/machina@2821 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/Action.cpp | 3 +- src/engine/Action.hpp | 58 +++++++++++++++++++ src/engine/ActionFactory.cpp | 4 +- src/engine/ActionFactory.hpp | 37 ++++++++++++ src/engine/Edge.cpp | 11 +++- src/engine/Edge.hpp | 67 ++++++++++++++++++++++ src/engine/Engine.cpp | 86 +++++++++++++++++----------- src/engine/JackDriver.cpp | 20 ++++++- src/engine/JackDriver.hpp | 3 +- src/engine/LearnRequest.cpp | 28 ++++++++++ src/engine/LearnRequest.hpp | 31 +++-------- src/engine/Loader.cpp | 12 ++-- src/engine/Machine.cpp | 37 +++++++----- src/engine/MachineBuilder.cpp | 6 +- src/engine/MidiAction.cpp | 6 +- src/engine/MidiAction.hpp | 59 ++++++++++++++++++++ src/engine/Mutation.cpp | 7 ++- src/engine/Node.cpp | 51 ++++++++++------- src/engine/Node.hpp | 104 ++++++++++++++++++++++++++++++++++ src/engine/Problem.cpp | 4 +- src/engine/SMFDriver.cpp | 18 +++--- src/engine/SMFDriver.hpp | 79 ++++++++++++++++++++++++++ src/engine/Stateful.cpp | 4 +- src/engine/Stateful.hpp | 67 ++++++++++++++++++++++ src/engine/machina/Action.hpp | 57 ------------------- src/engine/machina/ActionFactory.hpp | 37 ------------ src/engine/machina/Driver.hpp | 11 +++- src/engine/machina/Edge.hpp | 66 ---------------------- src/engine/machina/Engine.hpp | 17 +++--- src/engine/machina/Machine.hpp | 8 ++- src/engine/machina/MidiAction.hpp | 57 ------------------- src/engine/machina/Node.hpp | 105 ----------------------------------- src/engine/machina/SMFDriver.hpp | 79 -------------------------- src/engine/machina/Stateful.hpp | 48 ---------------- src/engine/machina/types.hpp | 6 ++ src/engine/wscript | 5 +- 36 files changed, 716 insertions(+), 582 deletions(-) create mode 100644 src/engine/Action.hpp create mode 100644 src/engine/ActionFactory.hpp create mode 100644 src/engine/Edge.hpp create mode 100644 src/engine/MidiAction.hpp create mode 100644 src/engine/Node.hpp create mode 100644 src/engine/SMFDriver.hpp create mode 100644 src/engine/Stateful.hpp delete mode 100644 src/engine/machina/Action.hpp delete mode 100644 src/engine/machina/ActionFactory.hpp delete mode 100644 src/engine/machina/Edge.hpp delete mode 100644 src/engine/machina/MidiAction.hpp delete mode 100644 src/engine/machina/Node.hpp delete mode 100644 src/engine/machina/SMFDriver.hpp delete mode 100644 src/engine/machina/Stateful.hpp (limited to 'src/engine') diff --git a/src/engine/Action.cpp b/src/engine/Action.cpp index 14f7158..67a41c2 100644 --- a/src/engine/Action.cpp +++ b/src/engine/Action.cpp @@ -17,7 +17,8 @@ #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Action.hpp" + +#include "Action.hpp" namespace Machina { diff --git a/src/engine/Action.hpp b/src/engine/Action.hpp new file mode 100644 index 0000000..ceeea6a --- /dev/null +++ b/src/engine/Action.hpp @@ -0,0 +1,58 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_ACTION_HPP +#define MACHINA_ACTION_HPP + +#include +#include + +#include "raul/MIDISink.hpp" +#include "raul/SharedPtr.hpp" +#include "raul/TimeSlice.hpp" + +#include "machina/types.hpp" + +#include "Stateful.hpp" + +namespace Machina { + + +/** An Action, executed on entering or exiting of a state. + */ +struct Action : public Raul::Deletable, public Stateful { + virtual void execute(SharedPtr sink, Raul::TimeStamp time) = 0; + + virtual void write_state(Redland::Model& model); +}; + + +class PrintAction : public Action { +public: + PrintAction(const std::string& msg) : _msg(msg) {} + + void execute(SharedPtr, Raul::TimeStamp time) + { std::cout << "t=" << time << ": " << _msg << std::endl; } + +private: + std::string _msg; +}; + + +} // namespace Machina + +#endif // MACHINA_ACTION_HPP diff --git a/src/engine/ActionFactory.cpp b/src/engine/ActionFactory.cpp index d486c7d..d5fc954 100644 --- a/src/engine/ActionFactory.cpp +++ b/src/engine/ActionFactory.cpp @@ -15,8 +15,8 @@ * along with Machina. If not, see . */ -#include "machina/ActionFactory.hpp" -#include "machina/MidiAction.hpp" +#include "ActionFactory.hpp" +#include "MidiAction.hpp" namespace Machina { diff --git a/src/engine/ActionFactory.hpp b/src/engine/ActionFactory.hpp new file mode 100644 index 0000000..04b0c74 --- /dev/null +++ b/src/engine/ActionFactory.hpp @@ -0,0 +1,37 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_ACTIONFACTORY_HPP +#define MACHINA_ACTIONFACTORY_HPP + +#include "raul/SharedPtr.hpp" + +namespace Machina { + +class Action; + + +namespace ActionFactory { + SharedPtr copy(SharedPtr copy); + SharedPtr note_on(unsigned char note); + SharedPtr note_off(unsigned char note); +} + + +} // namespace Machina + +#endif // MACHINA_ACTIONFACTORY_HPP diff --git a/src/engine/Edge.cpp b/src/engine/Edge.cpp index 47335fb..8acdca3 100644 --- a/src/engine/Edge.cpp +++ b/src/engine/Edge.cpp @@ -17,13 +17,20 @@ #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" + #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" + +#include "Edge.hpp" +#include "Node.hpp" namespace Machina { +void +Edge::set(URIInt key, const Raul::Atom& value) +{ + std::cout << "EDGE SET " << key << " = " << value << std::endl; +} void Edge::write_state(Redland::Model& model) diff --git a/src/engine/Edge.hpp b/src/engine/Edge.hpp new file mode 100644 index 0000000..8e34292 --- /dev/null +++ b/src/engine/Edge.hpp @@ -0,0 +1,67 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_EDGE_HPP +#define MACHINA_EDGE_HPP + +#include +#include + +#include "raul/DoubleBuffer.hpp" +#include "raul/SharedPtr.hpp" +#include "raul/WeakPtr.hpp" + +#include "machina/types.hpp" + +#include "Action.hpp" +#include "Stateful.hpp" + +namespace Machina { + +class Node; + +class Edge : public Stateful { +public: + Edge(WeakPtr tail, SharedPtr head) + : _probability(1.0f) + , _tail(tail) + , _head(head) + {} + + void set(URIInt key, const Raul::Atom& value); + void write_state(Redland::Model& model); + + WeakPtr tail() { return _tail; } + SharedPtr head() { return _head; } + + void set_tail(WeakPtr tail) { _tail = tail; } + void set_head(SharedPtr head) { _head = head; } + + inline float probability() { return _probability.get(); } + inline void set_probability(float p) { _probability.set(p); } + +private: + Raul::DoubleBuffer _probability; + + WeakPtr _tail; + SharedPtr _head; +}; + + +} // namespace Machina + +#endif // MACHINA_EDGE_HPP diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 612176a..03762b6 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -21,13 +21,21 @@ #include "machina/Engine.hpp" #include "machina/Loader.hpp" #include "machina/Machine.hpp" -#include "machina/SMFDriver.hpp" +#include "SMFDriver.hpp" #ifdef HAVE_JACK #include "JackDriver.hpp" #endif namespace Machina { +Engine::Engine(SharedPtr driver, Redland::World& rdf_world) + : _driver(driver) + , _rdf_world(rdf_world) + , _loader(_rdf_world) +{ +} + + SharedPtr Engine::new_driver(const std::string& name, SharedPtr machine) { @@ -39,7 +47,7 @@ Engine::new_driver(const std::string& name, SharedPtr machine) } #endif if (name == "smf") - return SharedPtr(new SMFDriver(machine)); + return SharedPtr(new SMFDriver(machine->time().unit())); std::cerr << "Error: Unknown driver type `" << name << "'" << std::endl; return SharedPtr(); @@ -51,54 +59,68 @@ Engine::new_driver(const std::string& name, SharedPtr machine) SharedPtr Engine::load_machine(const Glib::ustring& uri) { - SharedPtr old_machine = _driver->machine(); // Hold a reference to current machine.. - - SharedPtr m = _loader.load(uri); - if (m) { - m->activate(); - _driver->set_machine(m); + SharedPtr machine = _loader.load(uri); + SharedPtr old_machine; + if (machine) { + old_machine = _driver->machine(); // Keep a reference to old machine... + machine->activate(); + _driver->set_machine(machine); // Switch driver to new machine } // .. and drop it in this thread (to prevent deallocation in the RT thread) - return m; + return machine; } - -/** Load the machine at @a uri, and insert it into the current machine.. +/** Build a machine from the MIDI at @a uri, and run it (replacing current machine). * Safe to call while engine is processing. */ SharedPtr -Engine::import_machine(const Glib::ustring& uri) +Engine::load_machine_midi(const Glib::ustring& uri, double q, Raul::TimeDuration dur) { - SharedPtr m = _loader.load(uri); - if (m) { - m->activate(); - _driver->machine()->nodes().append(m->nodes()); + SharedPtr file_driver(new SMFDriver(dur.unit())); + SharedPtr machine = file_driver->learn(uri, q, dur); + SharedPtr old_machine; + if (machine) { + old_machine = _driver->machine(); // Keep a reference to old machine... + machine->activate(); + _driver->set_machine(machine); // Switch driver to new machine } - // Discard m + // .. and drop it in this thread (to prevent deallocation in the RT thread) - return _driver->machine(); + return machine; } - -/** Learn the SMF (MIDI) file at @a uri, add it to the current machine. - * Safe to call while engine is processing. - */ -SharedPtr -Engine::import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration duration) +void +Engine::import_machine(SharedPtr machine) { - SharedPtr file_driver(new SMFDriver()); - SharedPtr m = file_driver->learn(uri, q, duration); - m->activate(); - _driver->machine()->nodes().append(m->nodes()); - - // Discard m - - return _driver->machine(); + machine->activate(); + _driver->machine()->nodes().append(machine->nodes()); + // FIXME: thread safe? + // FIXME: announce } +void +Engine::export_midi(const Glib::ustring& filename, Raul::TimeDuration dur) +{ + SharedPtr machine = _driver->machine(); + SharedPtr file_driver(new Machina::SMFDriver(dur.unit())); + + const bool activated = _driver->is_activated(); + if (activated) + _driver->deactivate(); // FIXME: disable instead + + machine->set_sink(file_driver->writer()); + file_driver->writer()->start(filename, TimeStamp(dur.unit(), 0.0)); + file_driver->run(machine, dur); + machine->set_sink(_driver); + machine->reset(machine->time()); + file_driver->writer()->finish(); + + if (activated) + _driver->activate(); +} void Engine::set_bpm(double bpm) diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp index 6f3afe0..ca86111 100644 --- a/src/engine/JackDriver.cpp +++ b/src/engine/JackDriver.cpp @@ -19,10 +19,12 @@ #include #include "machina-config.h" -#include "machina/MidiAction.hpp" +#include "machina/URIs.hpp" +#include "machina/Updates.hpp" #include "JackDriver.hpp" #include "LearnRequest.hpp" +#include "MidiAction.hpp" #include "jack_compat.h" using namespace Raul; @@ -222,6 +224,18 @@ JackDriver::process_input(SharedPtr machine, const TimeSlice& time) learn->finish( TimeStamp(TimeUnit::frames(sample_rate()), jack_last_frame_time(_client) + ev.time, 0)); + + const uint64_t id = Stateful::next_id(); + write_set(_updates, id, + URIs::instance().rdf_type, + URIs::instance().machina_MidiAction_atom); + write_set(_updates, learn->node()->id(), + URIs::instance().machina_enter_action, + Raul::Atom((int32_t)id)); + write_set(_updates, id, + URIs::instance().machina_note_number, + Raul::Atom((int32_t)ev.buffer[1])); + machine->clear_pending_learn(); } } @@ -235,7 +249,7 @@ JackDriver::process_input(SharedPtr machine, const TimeSlice& time) void JackDriver::write_event(Raul::TimeStamp time, size_t size, - const byte* event) throw (std::logic_error) + const byte* event) { if (!_output_port) return; @@ -327,7 +341,7 @@ JackDriver::on_process(jack_nframes_t nframes) goto end; while (true) { - const uint32_t run_dur_frames = machine->run(_cycle_time); + const uint32_t run_dur_frames = machine->run(_cycle_time, _updates); if (run_dur_frames == 0) { // Machine didn't run at all (machine has no initial states) diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp index 756f717..133c7ed 100644 --- a/src/engine/JackDriver.hpp +++ b/src/engine/JackDriver.hpp @@ -25,7 +25,6 @@ #include "raul/Command.hpp" #include "raul/DoubleBuffer.hpp" -#include "raul/EventRingBuffer.hpp" #include "raul/Semaphore.hpp" #include "raul/SharedPtr.hpp" @@ -61,7 +60,7 @@ public: void write_event(Raul::TimeStamp time, size_t size, - const unsigned char* event) throw (std::logic_error); + const unsigned char* event); void set_bpm(double bpm) { _bpm.set(bpm); } void set_quantization(double q) { _quantization.set(q); } diff --git a/src/engine/LearnRequest.cpp b/src/engine/LearnRequest.cpp index 6643602..b103c65 100644 --- a/src/engine/LearnRequest.cpp +++ b/src/engine/LearnRequest.cpp @@ -21,6 +21,34 @@ namespace Machina { +LearnRequest::LearnRequest(SharedPtr maid, SharedPtr node) + : _started(false) + , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant + , _quantization(0) // irrelevant + , _node(node) + , _enter_action(new MidiAction(4, NULL)) + , _exit_action(new MidiAction(4, NULL)) +{ + maid->manage(_enter_action); + maid->manage(_exit_action); +} + +SharedPtr +LearnRequest::create(SharedPtr maid, SharedPtr node) +{ + SharedPtr ret(new LearnRequest(maid, node)); + maid->manage(ret); + return ret; +} + +void +LearnRequest::start(double q, Raul::TimeStamp time) +{ + _started = true; + _start_time = time; + _quantization = q; +} + /** Add the learned actions to the node */ void LearnRequest::finish(TimeStamp time) diff --git a/src/engine/LearnRequest.hpp b/src/engine/LearnRequest.hpp index 7d02564..3de98ea 100644 --- a/src/engine/LearnRequest.hpp +++ b/src/engine/LearnRequest.hpp @@ -21,10 +21,11 @@ #include "raul/Maid.hpp" #include "raul/SharedPtr.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" #include "machina/types.hpp" +#include "MidiAction.hpp" +#include "Node.hpp" + namespace Machina { class Node; @@ -35,38 +36,20 @@ class MidiAction; */ class LearnRequest : public Raul::Deletable { public: - static SharedPtr - create(SharedPtr maid, SharedPtr node) - { - SharedPtr ret(new LearnRequest(maid, node)); - maid->manage(ret); - return ret; - } - - void start(double q, Raul::TimeStamp time) - { _started = true; _start_time = time; _quantization = q; } + create(SharedPtr maid, SharedPtr node); + void start(double q, Raul::TimeStamp time); void finish(TimeStamp time); - bool started() { return _started; } + inline bool started() const { return _started; } const SharedPtr& node() { return _node; } const SharedPtr& enter_action() { return _enter_action; } const SharedPtr& exit_action() { return _exit_action; } private: - LearnRequest(SharedPtr maid, SharedPtr node) - : _started(false) - , _start_time(TimeUnit(TimeUnit::BEATS, 19200), 0, 0) // irrelevant - , _quantization(0) // irrelevant - , _node(node) - , _enter_action(new MidiAction(4, NULL)) - , _exit_action(new MidiAction(4, NULL)) - { - maid->manage(_enter_action); - maid->manage(_exit_action); - } + LearnRequest(SharedPtr maid, SharedPtr node); bool _started; TimeStamp _start_time; diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp index 78992d5..2698491 100644 --- a/src/engine/Loader.cpp +++ b/src/engine/Loader.cpp @@ -15,17 +15,21 @@ * along with Machina. If not, see . */ +#include #include #include -#include + #include + #include "redlandmm/Query.hpp" + #include "machina/Loader.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/ActionFactory.hpp" + #include "machina-config.h" +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "Node.hpp" using namespace Raul; using namespace std; diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index 18ce5de..32ac10d 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -17,20 +17,26 @@ #include +#include "raul/Atom.hpp" #include "raul/SharedPtr.hpp" #include "redlandmm/Model.hpp" #include "redlandmm/World.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" +#include "machina/Updates.hpp" +#include "machina/URIs.hpp" +#include "Edge.hpp" +#include "Node.hpp" #include "LearnRequest.hpp" +#include "MidiAction.hpp" using namespace std; using namespace Raul; +static const Raul::Atom true_atom(true); +static const Raul::Atom false_atom(false); + namespace Machina { @@ -162,7 +168,7 @@ Machine::remove_node(SharedPtr node) _nodes.erase(_nodes.find(node)); for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) - (*n)->remove_edges_to(node); + (*n)->remove_edge_to(node); } @@ -217,7 +223,7 @@ Machine::earliest_node() const * Returns true if node was entered, or false if the maximum active nodes has been reached. */ bool -Machine::enter_node(SharedPtr sink, SharedPtr node) +Machine::enter_node(SharedPtr sink, SharedPtr node, SharedPtr updates) { assert(!node->is_active()); @@ -229,6 +235,8 @@ Machine::enter_node(SharedPtr sink, SharedPtr node) node->enter(sink, _time); assert(node->is_active()); _active_nodes.at(index) = node; + + write_set(updates, node->id(), URIs::instance().machina_active, true_atom); return true; } index = (index + 1) % MAX_ACTIVE_NODES; @@ -243,9 +251,11 @@ Machine::enter_node(SharedPtr sink, SharedPtr node) /** Exit an active node at the current _time. */ void -Machine::exit_node(SharedPtr sink, SharedPtr node) +Machine::exit_node(SharedPtr sink, SharedPtr node, SharedPtr updates) { node->exit(sink, _time); + write_set(updates, node->id(), URIs::instance().machina_active, false_atom); + assert(!node->is_active()); for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) @@ -267,7 +277,7 @@ Machine::exit_node(SharedPtr sink, SharedPtr node) && rand_normal > range_min && rand_normal < range_min + (*s)->probability()) { - enter_node(sink, (*s)->head()); + enter_node(sink, (*s)->head(), updates); break; } else { @@ -286,7 +296,7 @@ Machine::exit_node(SharedPtr sink, SharedPtr node) SharedPtr head = (*e)->head(); if ( ! head->is_active()) - enter_node(sink, head); + enter_node(sink, head, updates); } } @@ -304,7 +314,7 @@ Machine::exit_node(SharedPtr sink, SharedPtr node) * with sample accuracy if necessary). */ uint32_t -Machine::run(const Raul::TimeSlice& time) +Machine::run(const Raul::TimeSlice& time, SharedPtr updates) { if (_is_finished) return 0; @@ -321,11 +331,13 @@ Machine::run(const Raul::TimeSlice& time) bool entered = false; if ( ! _nodes.empty()) { for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) { - if ((*n)->is_active()) + if ((*n)->is_active()) { (*n)->exit(sink, _time); + write_set(updates, (*n)->id(), URIs::instance().machina_active, false_atom); + } if ((*n)->is_initial()) { - if (enter_node(sink, (*n))) + if (enter_node(sink, (*n), updates)) entered = true; } } @@ -352,7 +364,7 @@ Machine::run(const Raul::TimeSlice& time) } else if (time.beats_to_ticks(earliest->exit_time()) < cycle_end_frames) { // Earliest active state ends this cycle _time = earliest->exit_time(); - exit_node(sink, earliest); + exit_node(sink, earliest, updates); } else { // Earliest active state ends in the future, done this cycle @@ -376,7 +388,6 @@ Machine::learn(SharedPtr maid, SharedPtr node) _pending_learn = LearnRequest::create(maid, node); } - void Machine::write_state(Redland::Model& model) { diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp index 629ce57..3bf9152 100644 --- a/src/engine/MachineBuilder.cpp +++ b/src/engine/MachineBuilder.cpp @@ -21,12 +21,12 @@ #include "raul/SharedPtr.hpp" #include "raul/Quantizer.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" -#include "machina/Node.hpp" +#include "Edge.hpp" +#include "Node.hpp" #include "MachineBuilder.hpp" +#include "MidiAction.hpp" using namespace std; using namespace Raul; diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp index e56202c..819e63b 100644 --- a/src/engine/MidiAction.cpp +++ b/src/engine/MidiAction.cpp @@ -16,11 +16,15 @@ */ #include + #include "raul/SharedPtr.hpp" #include "raul/MIDISink.hpp" #include "raul/Atom.hpp" #include "raul/AtomRDF.hpp" -#include "machina/MidiAction.hpp" + +#include "machina/types.hpp" + +#include "MidiAction.hpp" namespace Machina { diff --git a/src/engine/MidiAction.hpp b/src/engine/MidiAction.hpp new file mode 100644 index 0000000..f8b3fdc --- /dev/null +++ b/src/engine/MidiAction.hpp @@ -0,0 +1,59 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_MIDIACTION_HPP +#define MACHINA_MIDIACTION_HPP + +#include "raul/AtomicPtr.hpp" +#include "raul/TimeSlice.hpp" + +#include "machina/types.hpp" + +#include "Action.hpp" + +namespace Raul { class MIDISink; } + +namespace Machina { + + +class MidiAction : public Action { +public: + ~MidiAction(); + + MidiAction(size_t size, + const unsigned char* event); + + size_t event_size() { return _size; } + byte* event() { return _event.get(); } + + bool set_event(size_t size, const byte* event); + + void execute(SharedPtr driver, Raul::TimeStamp time); + + virtual void write_state(Redland::Model& model); + +private: + + size_t _size; + const size_t _max_size; + Raul::AtomicPtr _event; +}; + + +} // namespace Machina + +#endif // MACHINA_MIDIACTION_HPP diff --git a/src/engine/Mutation.cpp b/src/engine/Mutation.cpp index c41b968..55d5715 100644 --- a/src/engine/Mutation.cpp +++ b/src/engine/Mutation.cpp @@ -18,12 +18,13 @@ #include #include -#include "machina/ActionFactory.hpp" -#include "machina/Edge.hpp" #include "machina/Machine.hpp" -#include "machina/MidiAction.hpp" #include "machina/Mutation.hpp" +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "MidiAction.hpp" + using namespace std; namespace Machina { diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp index e150a6f..b7eaf66 100644 --- a/src/engine/Node.cpp +++ b/src/engine/Node.cpp @@ -21,9 +21,12 @@ #include "raul/AtomRDF.hpp" #include "redlandmm/World.hpp" #include "redlandmm/Model.hpp" -#include "machina/Node.hpp" -#include "machina/Edge.hpp" -#include "machina/ActionFactory.hpp" + +#include "machina/URIs.hpp" + +#include "ActionFactory.hpp" +#include "Edge.hpp" +#include "Node.hpp" using namespace Raul; using namespace std; @@ -32,24 +35,24 @@ namespace Machina { Node::Node(TimeDuration duration, bool initial) - : _is_initial(initial) + : _enter_time(duration.unit()) + , _duration(duration) + , _is_initial(initial) , _is_selector(false) , _is_active(false) - , _enter_time(duration.unit()) - , _duration(duration) { } Node::Node(const Node& copy) : Stateful() // don't copy RDF ID - , _is_initial(copy._is_initial) - , _is_selector(copy._is_selector) - , _is_active(false) , _enter_time(copy._enter_time) , _duration(copy._duration) , _enter_action(ActionFactory::copy(copy._enter_action)) , _exit_action(ActionFactory::copy(copy._exit_action)) + , _is_initial(copy._is_initial) + , _is_selector(copy._is_selector) + , _is_active(false) { for (Edges::const_iterator i = copy._edges.begin(); i != copy._edges.end(); ++i) { SharedPtr edge(new Edge(*i->get())); @@ -187,20 +190,30 @@ Node::connected_to(SharedPtr node) } -void -Node::remove_edges_to(SharedPtr node) +SharedPtr +Node::remove_edge_to(SharedPtr node) { - for (Edges::iterator i = _edges.begin(); i != _edges.end() ; ) { - Edges::iterator next = i; - ++next; - - if ((*i)->head() == node) + for (Edges::iterator i = _edges.begin(); i != _edges.end(); ++i) { + if ((*i)->head() == node) { + SharedPtr edge(*i); _edges.erase(i); - - i = next; + edges_changed(); + return edge; + } } - edges_changed(); + return SharedPtr(); +} + + +void +Node::set(URIInt key, const Raul::Atom& value) +{ + if (key == URIs::instance().machina_initial) { + set_initial(value.get_bool()); + } else if (key == URIs::instance().machina_selector) { + set_selector(value.get_bool()); + } } diff --git a/src/engine/Node.hpp b/src/engine/Node.hpp new file mode 100644 index 0000000..13f6bb3 --- /dev/null +++ b/src/engine/Node.hpp @@ -0,0 +1,104 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_NODE_HPP +#define MACHINA_NODE_HPP + +#include "raul/List.hpp" +#include "raul/MIDISink.hpp" +#include "raul/SharedPtr.hpp" + +#include "Action.hpp" +#include "Schrodinbit.hpp" +#include "Stateful.hpp" + +namespace Machina { + +class Edge; +using Raul::TimeDuration; +using Raul::TimeStamp; +using Raul::TimeUnit; + + +/** 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 Stateful { +public: + Node(TimeDuration duration, bool initial=false); + Node(const Node& copy); + + void set_enter_action(SharedPtr action); + void set_exit_action(SharedPtr action); + + SharedPtr enter_action() { return _enter_action; } + SharedPtr exit_action() { return _exit_action; } + + void enter(SharedPtr driver, TimeStamp time); + void exit(SharedPtr driver, TimeStamp time); + + void edges_changed(); + + void add_edge(SharedPtr edge); + void remove_edge(SharedPtr edge); + SharedPtr remove_edge_to(SharedPtr node); + bool connected_to(SharedPtr node); + + void set(URIInt key, const Raul::Atom& value); + void write_state(Redland::Model& model); + + 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 { assert(_is_active); return _enter_time; } + TimeStamp exit_time() const { assert(_is_active); return _enter_time + _duration; } + TimeDuration duration() const { return _duration; } + void set_duration(TimeDuration d) { _duration = d; } + bool is_selector() const { return _is_selector; } + void set_selector(bool i); + + inline bool changed() { return _changed; } + inline void set_changed() { _changed = true; } + + typedef Raul::List > Edges; + Edges& edges() { return _edges; } + + SharedPtr random_edge(); + +private: + Node& operator=(const Node& other); // undefined + + TimeStamp _enter_time; ///< valid iff _is_active + TimeDuration _duration; + SharedPtr _enter_action; + SharedPtr _exit_action; + Edges _edges; + Schrodinbit _changed; + bool _is_initial; + bool _is_selector; + bool _is_active; +}; + + +} // namespace Machina + +#endif // MACHINA_NODE_HPP diff --git a/src/engine/Problem.cpp b/src/engine/Problem.cpp index ecd1c6b..bc32667 100644 --- a/src/engine/Problem.cpp +++ b/src/engine/Problem.cpp @@ -23,13 +23,15 @@ #include #include "eugene/Problem.hpp" -#include "machina/ActionFactory.hpp" + #include "machina/Edge.hpp" #include "machina/Machine.hpp" + #include "raul/SMFReader.hpp" #include "raul/midi_events.h" #include "machina-config.h" +#include "ActionFactory.hpp" #include "Problem.hpp" using namespace std; diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp index b41ae49..3bf49c5 100644 --- a/src/engine/SMFDriver.cpp +++ b/src/engine/SMFDriver.cpp @@ -15,26 +15,30 @@ * along with Machina. If not, see . */ -#include #include +#include + #include + #include "raul/Quantizer.hpp" #include "raul/SharedPtr.hpp" #include "raul/SMFWriter.hpp" #include "raul/SMFReader.hpp" + #include "machina/Machine.hpp" -#include "machina/Edge.hpp" -#include "machina/SMFDriver.hpp" + +#include "Edge.hpp" +#include "SMFDriver.hpp" using namespace std; namespace Machina { -SMFDriver::SMFDriver(SharedPtr machine) - : Driver(machine) +SMFDriver::SMFDriver(Raul::TimeUnit unit) + : Driver(SharedPtr()) { - _writer = SharedPtr(new Raul::SMFWriter(machine->time().unit())); + _writer = SharedPtr(new Raul::SMFWriter(unit)); } @@ -144,7 +148,7 @@ SMFDriver::run(SharedPtr machine, Raul::TimeStamp max_time) Raul::TimeSlice time(machine->time().unit().ppt(), _writer->unit().ppt(), 120.0); time.set_slice(TimeStamp(max_time.unit(), 0, 0), time.beats_to_ticks(max_time)); machine->set_sink(shared_from_this()); - machine->run(time); + machine->run(time, SharedPtr()); } diff --git a/src/engine/SMFDriver.hpp b/src/engine/SMFDriver.hpp new file mode 100644 index 0000000..7081dc2 --- /dev/null +++ b/src/engine/SMFDriver.hpp @@ -0,0 +1,79 @@ +/* This file is part of Machina. + * Copyright (C) 2007-2009 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_SMFDRIVER_HPP +#define MACHINA_SMFDRIVER_HPP + +#include +#include + +#include "raul/SMFReader.hpp" +#include "raul/SMFWriter.hpp" +#include "raul/SharedPtr.hpp" + +#include "machina/Driver.hpp" +#include "machina/types.hpp" + +#include "MachineBuilder.hpp" + +namespace Machina { + +class Node; +class Machine; + + +class SMFDriver : public Driver, + public boost::enable_shared_from_this { +public: + SMFDriver(Raul::TimeUnit unit); + + SharedPtr learn(const std::string& filename, + double q, + Raul::TimeDuration max_duration); + + SharedPtr learn(const std::string& filename, + unsigned track, + double q, + Raul::TimeDuration max_duration); + + void run(SharedPtr machine, Raul::TimeStamp max_time); + + void write_event(Raul::TimeStamp time, + size_t ev_size, + const unsigned char* ev) throw (std::logic_error) + { _writer->write_event(time, ev_size, ev); } + + void set_bpm(double /*bpm*/) { } + void set_quantization(double /*quantization*/) { } + + SharedPtr writer() { return _writer; } + +private: + SharedPtr _writer; + + void learn_track(SharedPtr builder, + Raul::SMFReader& reader, + unsigned track, + double q, + Raul::TimeDuration max_duration); +}; + + +} // namespace Machina + +#endif // MACHINA_SMFDRIVER_HPP + diff --git a/src/engine/Stateful.cpp b/src/engine/Stateful.cpp index 0e1e3ad..75a1158 100644 --- a/src/engine/Stateful.cpp +++ b/src/engine/Stateful.cpp @@ -15,14 +15,14 @@ * along with Machina. If not, see . */ -#include "machina/Stateful.hpp" +#include "Stateful.hpp" namespace Machina { uint64_t Stateful::_next_id = 1; Stateful::Stateful() - : _id(_next_id++) + : _id(next_id()) { } diff --git a/src/engine/Stateful.hpp b/src/engine/Stateful.hpp new file mode 100644 index 0000000..08a1425 --- /dev/null +++ b/src/engine/Stateful.hpp @@ -0,0 +1,67 @@ +/* This file is part of Machina + * Copyright (C) 2007-2010 David 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 3 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 more details. + * + * You should have received a copy of the GNU General Public License + * along with Machina. If not, see . + */ + +#ifndef MACHINA_STATEFUL_HPP +#define MACHINA_STATEFUL_HPP + +#include + +#include "redlandmm/World.hpp" +#include "redlandmm/Model.hpp" + +#include "machina/types.hpp" + +namespace Raul { class Atom; } + +namespace Machina { + +class URIs; + +class Stateful { +public: + Stateful(); + + virtual ~Stateful() {} + + virtual void set(URIInt key, const Raul::Atom& value) {} + virtual void write_state(Redland::Model& model) = 0; + + uint64_t id() const { return _id; } + const Redland::Node& rdf_id(Redland::World& world) const; + + static uint64_t next_id() { return _next_id++; } + +protected: + Stateful(uint64_t id) : _id(id) {} + +private: + static uint64_t _next_id; + + uint64_t _id; + mutable Redland::Node _rdf_id; +}; + +class StatefulKey : public Stateful { +public: + StatefulKey(uint64_t id) : Stateful(id) {} + + void write_state(Redland::Model& model) {} +}; + +} // namespace Machina + +#endif // MACHINA_STATEFUL_HPP diff --git a/src/engine/machina/Action.hpp b/src/engine/machina/Action.hpp deleted file mode 100644 index 84181a3..0000000 --- a/src/engine/machina/Action.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_ACTION_HPP -#define MACHINA_ACTION_HPP - -#include -#include - -#include "raul/MIDISink.hpp" -#include "raul/SharedPtr.hpp" -#include "raul/TimeSlice.hpp" - -#include "Stateful.hpp" -#include "types.hpp" - -namespace Machina { - - -/** An Action, executed on entering or exiting of a state. - */ -struct Action : public Raul::Deletable, public Stateful { - virtual void execute(SharedPtr sink, Raul::TimeStamp time) = 0; - - virtual void write_state(Redland::Model& model); -}; - - -class PrintAction : public Action { -public: - PrintAction(const std::string& msg) : _msg(msg) {} - - void execute(SharedPtr, Raul::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/ActionFactory.hpp b/src/engine/machina/ActionFactory.hpp deleted file mode 100644 index 04b0c74..0000000 --- a/src/engine/machina/ActionFactory.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_ACTIONFACTORY_HPP -#define MACHINA_ACTIONFACTORY_HPP - -#include "raul/SharedPtr.hpp" - -namespace Machina { - -class Action; - - -namespace ActionFactory { - SharedPtr copy(SharedPtr copy); - SharedPtr note_on(unsigned char note); - SharedPtr note_off(unsigned char note); -} - - -} // namespace Machina - -#endif // MACHINA_ACTIONFACTORY_HPP diff --git a/src/engine/machina/Driver.hpp b/src/engine/machina/Driver.hpp index f850d3d..814f041 100644 --- a/src/engine/machina/Driver.hpp +++ b/src/engine/machina/Driver.hpp @@ -19,12 +19,14 @@ #define MACHINA_DRIVER_HPP #include "raul/MIDISink.hpp" +#include "raul/RingBuffer.hpp" + +#include "machina/types.hpp" namespace Machina { class Machine; - class Driver : public Raul::MIDISink { public: Driver(SharedPtr machine) : _machine(machine) {} @@ -33,9 +35,13 @@ public: SharedPtr machine() { return _machine; } virtual void set_machine(SharedPtr machine) { _machine = machine; } + SharedPtr update_sink() { return _updates; } + void set_update_sink(SharedPtr b) { _updates = b; } + virtual void set_bpm(double bpm) = 0; virtual void set_quantization(double q) = 0; + virtual bool is_activated() const { return false; } virtual void activate() {} virtual void deactivate() {} @@ -46,7 +52,8 @@ public: virtual void finish_record() {} protected: - SharedPtr _machine; + SharedPtr _machine; + SharedPtr _updates; }; diff --git a/src/engine/machina/Edge.hpp b/src/engine/machina/Edge.hpp deleted file mode 100644 index 8a2d1c2..0000000 --- a/src/engine/machina/Edge.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_EDGE_HPP -#define MACHINA_EDGE_HPP - -#include -#include - -#include "raul/DoubleBuffer.hpp" -#include "raul/SharedPtr.hpp" -#include "raul/WeakPtr.hpp" - -#include "Action.hpp" -#include "Stateful.hpp" -#include "types.hpp" - -namespace Machina { - -class Node; - -class Edge : public Stateful { -public: - - Edge(WeakPtr tail, SharedPtr head) - : _probability(1.0f) - , _tail(tail) - , _head(head) - {} - - void write_state(Redland::Model& model); - - WeakPtr tail() { return _tail; } - SharedPtr head() { return _head; } - - void set_tail(WeakPtr tail) { _tail = tail; } - void set_head(SharedPtr head) { _head = head; } - - inline float probability() { return _probability.get(); } - inline void set_probability(float p) { _probability.set(p); } - -private: - Raul::DoubleBuffer _probability; - - WeakPtr _tail; - SharedPtr _head; -}; - - -} // namespace Machina - -#endif // MACHINA_EDGE_HPP diff --git a/src/engine/machina/Engine.hpp b/src/engine/machina/Engine.hpp index 17d555d..022a2ca 100644 --- a/src/engine/machina/Engine.hpp +++ b/src/engine/machina/Engine.hpp @@ -34,12 +34,7 @@ class Machine; class Engine { public: - Engine(SharedPtr driver, Redland::World& rdf_world) - : _driver(driver) - , _rdf_world(rdf_world) - , _loader(_rdf_world) - { - } + Engine(SharedPtr driver, Redland::World& rdf_world); Redland::World& rdf_world() { return _rdf_world; } @@ -50,8 +45,14 @@ public: SharedPtr machine() { return _driver->machine(); } SharedPtr load_machine(const Glib::ustring& uri); - SharedPtr import_machine(const Glib::ustring& uri); - SharedPtr import_midi(const Glib::ustring& uri, double q, Raul::TimeDuration d); + SharedPtr load_machine_midi(const Glib::ustring& uri, + double q, + Raul::TimeDuration dur); + + void import_machine(SharedPtr machine); + + void export_midi(const Glib::ustring& filename, + Raul::TimeDuration dur); void set_bpm(double bpm); void set_quantization(double beat_fraction); diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp index e1a0f25..f3469c7 100644 --- a/src/engine/machina/Machine.hpp +++ b/src/engine/machina/Machine.hpp @@ -23,6 +23,7 @@ #include "raul/List.hpp" #include "raul/Maid.hpp" +#include "raul/RingBuffer.hpp" #include "raul/SharedPtr.hpp" #include "raul/TimeSlice.hpp" #include "raul/WeakPtr.hpp" @@ -33,6 +34,7 @@ namespace Machina { +class Controller; class LearnRequest; /** A (Finite State) Machine. @@ -63,7 +65,7 @@ public: // Audio context void reset(Raul::TimeStamp time); - uint32_t run(const Raul::TimeSlice& time); + uint32_t run(const Raul::TimeSlice& time, SharedPtr updates); // Any context inline Raul::TimeStamp time() const { return _time; } @@ -84,8 +86,8 @@ private: // Audio context SharedPtr earliest_node() const; - bool enter_node(SharedPtr sink, SharedPtr node); - void exit_node(SharedPtr sink, SharedPtr); + bool enter_node(SharedPtr sink, SharedPtr node, SharedPtr updates); + void exit_node(SharedPtr sink, SharedPtr, SharedPtr updates); static const size_t MAX_ACTIVE_NODES = 128; std::vector< SharedPtr > _active_nodes; diff --git a/src/engine/machina/MidiAction.hpp b/src/engine/machina/MidiAction.hpp deleted file mode 100644 index 73aed7b..0000000 --- a/src/engine/machina/MidiAction.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_MIDIACTION_HPP -#define MACHINA_MIDIACTION_HPP - -#include "raul/AtomicPtr.hpp" -#include "raul/TimeSlice.hpp" -#include "types.hpp" -#include "Action.hpp" - -namespace Raul { class MIDISink; } - -namespace Machina { - - -class MidiAction : public Action { -public: - ~MidiAction(); - - MidiAction(size_t size, - const unsigned char* event); - - size_t event_size() { return _size; } - byte* event() { return _event.get(); } - - bool set_event(size_t size, const byte* event); - - void execute(SharedPtr driver, Raul::TimeStamp time); - - virtual void write_state(Redland::Model& model); - -private: - - size_t _size; - const size_t _max_size; - Raul::AtomicPtr _event; -}; - - -} // namespace Machina - -#endif // MACHINA_MIDIACTION_HPP diff --git a/src/engine/machina/Node.hpp b/src/engine/machina/Node.hpp deleted file mode 100644 index 57f62f1..0000000 --- a/src/engine/machina/Node.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_NODE_HPP -#define MACHINA_NODE_HPP - -#include "raul/List.hpp" -#include "raul/MIDISink.hpp" -#include "raul/SharedPtr.hpp" - -#include "Action.hpp" -#include "Schrodinbit.hpp" -#include "Stateful.hpp" - -namespace Machina { - -class Edge; -using Raul::TimeDuration; -using Raul::TimeStamp; -using Raul::TimeUnit; - - -/** 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 Stateful { -public: - typedef std::string ID; - - Node(TimeDuration duration, bool initial=false); - Node(const Node& copy); - - void set_enter_action(SharedPtr action); - void set_exit_action(SharedPtr action); - - SharedPtr enter_action() { return _enter_action; } - SharedPtr exit_action() { return _exit_action; } - - void enter(SharedPtr driver, TimeStamp time); - void exit(SharedPtr driver, TimeStamp time); - - void edges_changed(); - - void add_edge(SharedPtr edge); - void remove_edge(SharedPtr edge); - void remove_edges_to(SharedPtr node); - bool connected_to(SharedPtr node); - - void write_state(Redland::Model& model); - - 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 { assert(_is_active); return _enter_time; } - TimeStamp exit_time() const { assert(_is_active); return _enter_time + _duration; } - TimeDuration duration() { return _duration; } - void set_duration(TimeDuration d) { _duration = d; } - bool is_selector() const { return _is_selector; } - void set_selector(bool i); - - inline bool changed() { return _changed; } - inline void set_changed() { _changed = true; } - - typedef Raul::List > Edges; - Edges& edges() { return _edges; } - - SharedPtr random_edge(); - -private: - Node& operator=(const Node& other); // undefined - - Schrodinbit _changed; - bool _is_initial; - bool _is_selector; - bool _is_active; - TimeStamp _enter_time; ///< valid iff _is_active - TimeDuration _duration; - SharedPtr _enter_action; - SharedPtr _exit_action; - Edges _edges; -}; - - -} // namespace Machina - -#endif // MACHINA_NODE_HPP diff --git a/src/engine/machina/SMFDriver.hpp b/src/engine/machina/SMFDriver.hpp deleted file mode 100644 index a10442d..0000000 --- a/src/engine/machina/SMFDriver.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Machina. - * Copyright (C) 2007-2009 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_SMFDRIVER_HPP -#define MACHINA_SMFDRIVER_HPP - -#include -#include - -#include "raul/SMFReader.hpp" -#include "raul/SMFWriter.hpp" -#include "raul/SharedPtr.hpp" - -#include "machina/Driver.hpp" -#include "machina/types.hpp" - -#include "MachineBuilder.hpp" - -namespace Machina { - -class Node; -class Machine; - - -class SMFDriver : public Driver, - public boost::enable_shared_from_this { -public: - SMFDriver(SharedPtr machine = SharedPtr()); - - SharedPtr learn(const std::string& filename, - double q, - Raul::TimeDuration max_duration); - - SharedPtr learn(const std::string& filename, - unsigned track, - double q, - Raul::TimeDuration max_duration); - - void run(SharedPtr machine, Raul::TimeStamp max_time); - - void write_event(Raul::TimeStamp time, - size_t ev_size, - const unsigned char* ev) throw (std::logic_error) - { _writer->write_event(time, ev_size, ev); } - - void set_bpm(double /*bpm*/) { } - void set_quantization(double /*quantization*/) { } - - SharedPtr writer() { return _writer; } - -private: - SharedPtr _writer; - - void learn_track(SharedPtr builder, - Raul::SMFReader& reader, - unsigned track, - double q, - Raul::TimeDuration max_duration); -}; - - -} // namespace Machina - -#endif // MACHINA_SMFDRIVER_HPP - diff --git a/src/engine/machina/Stateful.hpp b/src/engine/machina/Stateful.hpp deleted file mode 100644 index f35c00a..0000000 --- a/src/engine/machina/Stateful.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Machina - * Copyright (C) 2007-2010 David 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 3 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 more details. - * - * You should have received a copy of the GNU General Public License - * along with Machina. If not, see . - */ - -#ifndef MACHINA_STATEFUL_HPP -#define MACHINA_STATEFUL_HPP - -#include - -#include "redlandmm/World.hpp" -#include "redlandmm/Model.hpp" - -namespace Machina { - -class Stateful { -public: - Stateful(); - - virtual ~Stateful() {} - - virtual void write_state(Redland::Model& model) = 0; - - uint64_t id() const { return _id; } - const Redland::Node& rdf_id(Redland::World& world) const; - -private: - static uint64_t _next_id; - - uint64_t _id; - mutable Redland::Node _rdf_id; -}; - -} // namespace Machina - -#endif // MACHINA_STATEFUL_HPP diff --git a/src/engine/machina/types.hpp b/src/engine/machina/types.hpp index c39b682..74410d9 100644 --- a/src/engine/machina/types.hpp +++ b/src/engine/machina/types.hpp @@ -18,10 +18,16 @@ #ifndef MACHINA_TYPES_HPP #define MACHINA_TYPES_HPP +#include "raul/RingBuffer.hpp" + namespace Machina { typedef unsigned char byte; +typedef Raul::RingBuffer UpdateBuffer; + +typedef uint32_t URIInt; + } // namespace Machina #endif // MACHINA_TYPES_HPP diff --git a/src/engine/wscript b/src/engine/wscript index 35f1303..1566a72 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -5,6 +5,7 @@ def build(bld): core_source = ''' Action.cpp ActionFactory.cpp + Controller.cpp Edge.cpp Engine.cpp JackDriver.cpp @@ -18,6 +19,8 @@ def build(bld): Recorder.cpp SMFDriver.cpp Stateful.cpp + Updates.cpp + URIs.cpp ''' if bld.env['HAVE_EUGENE']: core_source += ''' @@ -27,7 +30,7 @@ def build(bld): obj = bld(features = 'cxx cxxshlib') obj.source = core_source obj.export_includes = ['.'] - obj.includes = ['.', '../..'] + obj.includes = ['.', '..', '../..'] obj.name = 'libmachina_engine' obj.target = 'machina_engine' core_libs = 'GLIBMM GTHREAD RAUL REDLANDMM JACK' -- cgit v1.2.1