ian@0
|
1 // Copyright 2011, Ian Hobson.
|
ian@0
|
2 //
|
ian@0
|
3 // This file is part of gpsynth.
|
ian@0
|
4 //
|
ian@0
|
5 // gpsynth is free software: you can redistribute it and/or modify
|
ian@0
|
6 // it under the terms of the GNU General Public License as published by
|
ian@0
|
7 // the Free Software Foundation, either version 3 of the License, or
|
ian@0
|
8 // (at your option) any later version.
|
ian@0
|
9 //
|
ian@0
|
10 // gpsynth is distributed in the hope that it will be useful,
|
ian@0
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
ian@0
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
ian@0
|
13 // GNU General Public License for more details.
|
ian@0
|
14 //
|
ian@0
|
15 // You should have received a copy of the GNU General Public License
|
ian@0
|
16 // along with gpsynth in the file COPYING.
|
ian@0
|
17 // If not, see http://www.gnu.org/licenses/.
|
ian@0
|
18
|
ian@0
|
19 // SuperCollider grammar, resonsible for generating and altering SuperCollider
|
ian@0
|
20 // synth graphs
|
ian@0
|
21
|
ian@0
|
22 #pragma once
|
ian@0
|
23
|
ian@0
|
24 #include "grammar.hpp"
|
ian@0
|
25 #include "range.hpp"
|
ian@0
|
26 #include "synth_graph.hpp"
|
ian@0
|
27
|
ian@0
|
28 #include <map>
|
ian@0
|
29 #include <string>
|
ian@0
|
30 #include <vector>
|
ian@0
|
31
|
ian@0
|
32 namespace sc {
|
ian@0
|
33
|
ian@0
|
34 struct Argument {
|
ian@0
|
35
|
ian@0
|
36 enum ScalingMode {
|
ian@0
|
37 kScalingLinear,
|
ian@0
|
38 kScalingLog,
|
ian@0
|
39 kConstant
|
ian@0
|
40 };
|
ian@0
|
41
|
ian@0
|
42 std::string name_;
|
ian@0
|
43 stdx::Range<double> range_;
|
ian@0
|
44 stdx::Range<double> range_control_;
|
ian@0
|
45 ScalingMode scaling_mode_;
|
ian@0
|
46 double constant_value_;
|
ian@0
|
47 bool fixed_range_;
|
ian@0
|
48
|
ian@0
|
49 Argument(const std::string name = "")
|
ian@0
|
50 : name_(name),
|
ian@0
|
51 range_(0, 1),
|
ian@0
|
52 range_control_(0, 1),
|
ian@0
|
53 scaling_mode_(kScalingLinear),
|
ian@0
|
54 constant_value_(0),
|
ian@0
|
55 fixed_range_(false)
|
ian@0
|
56 {}
|
ian@0
|
57 };
|
ian@0
|
58
|
ian@0
|
59 class Command {
|
ian@0
|
60 public:
|
ian@0
|
61 enum CommandMode {
|
ian@0
|
62 kSource,
|
ian@0
|
63 kModifier,
|
ian@0
|
64 kSpecial,
|
ian@0
|
65 kNumberOfModes
|
ian@0
|
66 };
|
ian@0
|
67
|
ian@0
|
68 enum SpecialCommands {
|
ian@0
|
69 kMixer,
|
ian@0
|
70 kMultiplier,
|
ian@0
|
71 kNumberOfSpecialCommands
|
ian@0
|
72 };
|
ian@0
|
73
|
ian@0
|
74 enum OutputType {
|
ian@0
|
75 kAll,
|
ian@0
|
76 kAudio,
|
ian@0
|
77 kControl,
|
ian@0
|
78 };
|
ian@0
|
79
|
ian@0
|
80 private:
|
ian@0
|
81 std::string name_;
|
ian@0
|
82 std::vector<Argument> arguments_;
|
ian@0
|
83 CommandMode mode_;
|
ian@0
|
84 OutputType output_;
|
ian@0
|
85
|
ian@0
|
86 public:
|
ian@0
|
87 Command(const std::string& name,
|
ian@0
|
88 CommandMode mode,
|
ian@0
|
89 OutputType output = kAll,
|
ian@0
|
90 const std::vector<Argument>& arguments = std::vector<Argument>())
|
ian@0
|
91 : name_(name),
|
ian@0
|
92 mode_(mode),
|
ian@0
|
93 output_(output),
|
ian@0
|
94 arguments_(arguments)
|
ian@0
|
95 {}
|
ian@0
|
96
|
ian@0
|
97 CommandMode Mode() const { return mode_; }
|
ian@0
|
98 OutputType Output() const { return output_; }
|
ian@0
|
99 const std::string& Name() const { return name_; }
|
ian@0
|
100 const std::vector<Argument>& Arguments() const { return arguments_;}
|
ian@0
|
101 const Argument& GetArgument(int argument) const {
|
ian@0
|
102 return arguments_[argument];
|
ian@0
|
103 }
|
ian@0
|
104 bool IsAudioSource() { return (mode_ == kSource) && (output_ != kControl); }
|
ian@0
|
105 };
|
ian@0
|
106
|
ian@0
|
107 class Grammar : public GrammarInterface {
|
ian@0
|
108 // holds the commands available to the grammar
|
ian@0
|
109 std::vector<Command> commands_;
|
ian@0
|
110 typedef std::vector<Command>::size_type CommandID;
|
ian@0
|
111 int max_depth_;
|
ian@0
|
112
|
ian@0
|
113 public:
|
ian@0
|
114 // used when generating trees to indicate current tree state
|
ian@0
|
115 enum TreeMode {
|
ian@0
|
116 kTreeMode_Command,
|
ian@0
|
117 kTreeMode_Mod
|
ian@0
|
118 };
|
ian@0
|
119
|
ian@0
|
120 Grammar(const std::string& json_data);
|
ian@0
|
121
|
ian@0
|
122 void ParseJSON(const std::string& json_data);
|
ian@0
|
123
|
ian@0
|
124 const std::vector<Command>& Commands() const { return commands_; }
|
ian@0
|
125
|
ian@0
|
126 void SetMaximumDepth(int max_depth) { max_depth_ = max_depth; }
|
ian@0
|
127
|
ian@0
|
128 void RandomGraph(sg::Graph& graph) const;
|
ian@0
|
129 void PickCrossoverNodes(const sg::Graph& parent_1,
|
ian@0
|
130 const sg::Graph& parent_2,
|
ian@0
|
131 sg::Vertex* crossover_node_1,
|
ian@0
|
132 sg::Vertex* crossover_node_2) const;
|
ian@0
|
133 bool MutationReplaceSubTree(sg::Graph& graph) const;
|
ian@0
|
134 bool MutationAddSubTree(sg::Graph& graph) const;
|
ian@0
|
135 bool MutationModifyInputs(sg::Graph& graph) const;
|
ian@0
|
136 bool MutationModifyConnections(sg::Graph& graph) const;
|
ian@0
|
137 bool MutationReplaceCommand(sg::Graph& graph) const;
|
ian@0
|
138 bool MutationInsertCommand(sg::Graph& graph) const;
|
ian@0
|
139
|
ian@0
|
140 private:
|
ian@0
|
141 int RandomCommand(sg::CommandRate rate,
|
ian@0
|
142 int tree_depth,
|
ian@0
|
143 bool must_be_modifier) const;
|
ian@0
|
144 int RandomParameter(sg::Graph& graph) const;
|
ian@0
|
145
|
ian@0
|
146 sg::Vertex RandomTree(sg::Graph& graph,
|
ian@0
|
147 sg::CommandRate rate,
|
ian@0
|
148 TreeMode tree_mode,
|
ian@0
|
149 int depth) const;
|
ian@0
|
150
|
ian@0
|
151 sg::Vertex SpecialCommand(int command_id,
|
ian@0
|
152 sg::Graph& graph,
|
ian@0
|
153 sg::CommandRate output_mode,
|
ian@0
|
154 TreeMode tree_mode,
|
ian@0
|
155 int depth = 0,
|
ian@0
|
156 int minimum_channels = 2) const;
|
ian@0
|
157 void AddTreeToSpecialCommand(sg::Vertex command,
|
ian@0
|
158 sg::Graph& graph,
|
ian@0
|
159 int input_id,
|
ian@0
|
160 TreeMode tree_mode,
|
ian@0
|
161 sg::CommandRate command_rate,
|
ian@0
|
162 bool* constant_added,
|
ian@0
|
163 std::set<int>* parameters,
|
ian@0
|
164 int depth) const;
|
ian@0
|
165 sg::Vertex CreateCommand(sg::Graph &graph,
|
ian@0
|
166 sg::CommandRate rate,
|
ian@0
|
167 int depth,
|
ian@0
|
168 bool must_be_modifier = false,
|
ian@0
|
169 bool make_modifier_input = true) const;
|
ian@0
|
170 int GetCommandInputID(int command_id) const;
|
ian@0
|
171 const Argument& GetCommandArgument(int command_id, int argument_id) const;
|
ian@0
|
172 const std::vector<sc::Argument>& CommandArguments(int command) const;
|
ian@0
|
173 };
|
ian@0
|
174
|
ian@0
|
175 } // sc namespace
|