diff src/sc_grammar.hpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sc_grammar.hpp	Thu Aug 25 11:05:55 2011 +0100
@@ -0,0 +1,175 @@
+//  Copyright 2011, Ian Hobson.
+//
+//  This file is part of gpsynth.
+//
+//  gpsynth 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.
+//
+//  gpsynth 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 gpsynth in the file COPYING. 
+//  If not, see http://www.gnu.org/licenses/.
+
+// SuperCollider grammar, resonsible for generating and altering SuperCollider
+// synth graphs
+
+#pragma once
+
+#include "grammar.hpp"
+#include "range.hpp"
+#include "synth_graph.hpp"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace sc {
+
+struct Argument {
+  
+  enum ScalingMode {
+    kScalingLinear,
+    kScalingLog,
+    kConstant
+  };
+  
+  std::string name_;
+  stdx::Range<double> range_;
+  stdx::Range<double> range_control_;
+  ScalingMode scaling_mode_;
+  double constant_value_;
+  bool fixed_range_;
+  
+  Argument(const std::string name = "")
+  : name_(name),
+    range_(0, 1),
+    range_control_(0, 1),
+    scaling_mode_(kScalingLinear),
+    constant_value_(0),
+    fixed_range_(false)
+  {}
+};
+
+class Command {
+public:
+  enum CommandMode {
+    kSource,
+    kModifier,
+    kSpecial,
+    kNumberOfModes
+  };
+  
+  enum SpecialCommands {
+    kMixer,
+    kMultiplier,
+    kNumberOfSpecialCommands
+  };
+  
+  enum OutputType {
+    kAll,
+    kAudio,
+    kControl,
+  };
+
+private:
+  std::string name_;
+  std::vector<Argument> arguments_;
+  CommandMode mode_;
+  OutputType output_;
+  
+public:
+  Command(const std::string& name,
+          CommandMode mode,
+          OutputType output = kAll,
+          const std::vector<Argument>& arguments = std::vector<Argument>())
+  : name_(name),
+    mode_(mode),
+    output_(output),
+    arguments_(arguments)
+  {}
+  
+  CommandMode Mode() const { return mode_; }
+  OutputType Output() const { return output_; }
+  const std::string& Name() const { return name_; }
+  const std::vector<Argument>& Arguments() const { return arguments_;}
+  const Argument& GetArgument(int argument) const {
+    return arguments_[argument];
+  }
+  bool IsAudioSource() { return (mode_ == kSource) && (output_ != kControl); }
+};
+
+class Grammar : public GrammarInterface {
+  // holds the commands available to the grammar
+  std::vector<Command> commands_;
+  typedef std::vector<Command>::size_type CommandID;
+  int max_depth_;
+
+public:
+  // used when generating trees to indicate current tree state
+  enum TreeMode {
+    kTreeMode_Command,
+    kTreeMode_Mod
+  };
+  
+  Grammar(const std::string& json_data);
+  
+  void ParseJSON(const std::string& json_data);
+  
+  const std::vector<Command>& Commands() const { return commands_; }
+  
+  void SetMaximumDepth(int max_depth) { max_depth_ = max_depth; }
+  
+  void RandomGraph(sg::Graph& graph) const;
+  void PickCrossoverNodes(const sg::Graph& parent_1, 
+                          const sg::Graph& parent_2,
+                          sg::Vertex* crossover_node_1,
+                          sg::Vertex* crossover_node_2) const;
+  bool MutationReplaceSubTree(sg::Graph& graph) const;
+  bool MutationAddSubTree(sg::Graph& graph) const;
+  bool MutationModifyInputs(sg::Graph& graph) const;
+  bool MutationModifyConnections(sg::Graph& graph) const;
+  bool MutationReplaceCommand(sg::Graph& graph) const;
+  bool MutationInsertCommand(sg::Graph& graph) const;
+  
+private:
+  int RandomCommand(sg::CommandRate rate,
+                    int tree_depth,
+                    bool must_be_modifier) const;
+  int RandomParameter(sg::Graph& graph) const;
+  
+  sg::Vertex RandomTree(sg::Graph& graph,
+                        sg::CommandRate rate,
+                        TreeMode tree_mode,
+                        int depth) const;
+  
+  sg::Vertex SpecialCommand(int command_id,
+                            sg::Graph& graph,
+                            sg::CommandRate output_mode,
+                            TreeMode tree_mode,
+                            int depth = 0,
+                            int minimum_channels = 2) const;
+  void AddTreeToSpecialCommand(sg::Vertex command,
+                               sg::Graph& graph,
+                               int input_id,
+                               TreeMode tree_mode,
+                               sg::CommandRate command_rate,
+                               bool* constant_added,
+                               std::set<int>* parameters,
+                               int depth) const;
+  sg::Vertex CreateCommand(sg::Graph &graph,
+                           sg::CommandRate rate,
+                           int depth,
+                           bool must_be_modifier = false,
+                           bool make_modifier_input = true) const;
+  int GetCommandInputID(int command_id) const;
+  const Argument& GetCommandArgument(int command_id, int argument_id) const;
+  const std::vector<sc::Argument>& CommandArguments(int command) const;
+};
+  
+} // sc namespace