/* 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 "machina/Edge.hpp" #include "machina/Machine.hpp" #include "machina/MachineMutation.hpp" #include "machina/ActionFactory.hpp" using namespace std; namespace Machina { namespace Mutation { void Compress::mutate(Machine& machine) { // Trim disconnected nodes for (Machine::Nodes::iterator i = machine.nodes().begin(); i != machine.nodes().end() ;) { Machine::Nodes::iterator next = i; ++next; if ((*i)->edges().empty()) machine.remove_node(*i); i = next; } } void AddNode::mutate(Machine& machine) { // Create random node SharedPtr node(new Node(1.0)); uint8_t note = rand() % 128; node->set_enter_action(ActionFactory::note_on(note)); node->set_exit_action(ActionFactory::note_off(note)); machine.add_node(node); // Add as a successor to some other random node SharedPtr tail = machine.random_node(); if (tail && tail != node) tail->add_edge(boost::shared_ptr(new Edge(tail, node))); } void RemoveNode::mutate(Machine& machine) { SharedPtr node = machine.random_node(); machine.remove_node(node); } void AdjustNode::mutate(Machine& machine) { SharedPtr node = machine.random_node(); if (node) { SharedPtr enter_action = PtrCast(node->enter_action()); SharedPtr exit_action = PtrCast(node->exit_action()); if (enter_action && exit_action) { const uint8_t note = rand() % 128; enter_action->event()[1] = note; exit_action->event()[1] = note; } node->set_changed(); } } void AddEdge::mutate(Machine& machine) { SharedPtr tail = machine.random_node(); SharedPtr head = machine.random_node(); if (tail && head && tail != head && !tail->connected_to(head)) tail->add_edge(boost::shared_ptr(new Edge(tail, head))); } void RemoveEdge::mutate(Machine& machine) { SharedPtr tail = machine.random_node(); if (tail) tail->remove_edge(tail->random_edge()); } void AdjustEdge::mutate(Machine& machine) { SharedPtr edge = machine.random_edge(); if (edge) edge->set_probability(rand() / (float)RAND_MAX); } } // namespace Mutation } // namespace Machina