/* This file is part of Machina. * Copyright 2007-2011 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 . */ #include #include "machina_config.h" #include "machina/Engine.hpp" #include "machina/Loader.hpp" #include "machina/Machine.hpp" #include "SMFDriver.hpp" #ifdef HAVE_JACK #include "JackDriver.hpp" #endif namespace machina { Engine::Engine(Raul::Forge& forge, SPtr driver, Sord::World& rdf_world) : _driver(driver) , _rdf_world(rdf_world) , _loader(_forge, _rdf_world) , _forge(forge) {} SPtr Engine::new_driver(Raul::Forge& forge, const std::string& name, SPtr machine) { #ifdef HAVE_JACK if (name == "jack") { JackDriver* driver = new JackDriver(forge, machine); driver->attach("machina"); return SPtr(driver); } #endif if (name == "smf") { return SPtr(new SMFDriver(forge, machine->time().unit())); } std::cerr << "Error: Unknown driver type `" << name << "'" << std::endl; return SPtr(); } /** Load the machine at @a uri, and run it (replacing current machine). * Safe to call while engine is processing. */ SPtr Engine::load_machine(const Glib::ustring& uri) { SPtr machine = _loader.load(uri); SPtr 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 machine; } /** Build a machine from the MIDI at @a uri, and run it (replacing current machine). * Safe to call while engine is processing. */ SPtr Engine::load_machine_midi(const Glib::ustring& uri, double q, Raul::TimeDuration dur) { SPtr file_driver(new SMFDriver(_forge, dur.unit())); SPtr machine = file_driver->learn(uri, q, dur); SPtr 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 machine; } void Engine::import_machine(SPtr machine) { machine->activate(); _driver->machine()->nodes().insert(machine->nodes().begin(), machine->nodes().end()); // FIXME: thread safe? // FIXME: announce } void Engine::export_midi(const Glib::ustring& filename, Raul::TimeDuration dur) { SPtr machine = _driver->machine(); SPtr file_driver( new machina::SMFDriver(_forge, dur.unit())); const bool activated = _driver->is_activated(); if (activated) { _driver->deactivate(); // FIXME: disable instead } file_driver->writer()->start(filename, TimeStamp(dur.unit(), 0.0)); file_driver->run(machine, dur); machine->reset(NULL, machine->time()); file_driver->writer()->finish(); if (activated) { _driver->activate(); } } void Engine::set_bpm(double bpm) { _driver->set_bpm(bpm); } void Engine::set_quantization(double q) { _driver->set_quantization(q); } } // namespace machina