Mercurial > hg > gpsynth
comparison src/program_options.cpp @ 0:add35537fdbb tip
Initial import
author | irh <ian.r.hobson@gmail.com> |
---|---|
date | Thu, 25 Aug 2011 11:05:55 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:add35537fdbb |
---|---|
1 // Copyright 2011, Ian Hobson. | |
2 // | |
3 // This file is part of gpsynth. | |
4 // | |
5 // gpsynth is free software: you can redistribute it and/or modify | |
6 // it under the terms of the GNU General Public License as published by | |
7 // the Free Software Foundation, either version 3 of the License, or | |
8 // (at your option) any later version. | |
9 // | |
10 // gpsynth is distributed in the hope that it will be useful, | |
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 // GNU General Public License for more details. | |
14 // | |
15 // You should have received a copy of the GNU General Public License | |
16 // along with gpsynth in the file COPYING. | |
17 // If not, see http://www.gnu.org/licenses/. | |
18 | |
19 #include "program_options.hpp" | |
20 | |
21 #include "boost/filesystem.hpp" | |
22 #include "boost/program_options.hpp" | |
23 | |
24 #include <ctime> | |
25 | |
26 namespace bf = boost::filesystem; | |
27 namespace bo = boost::program_options; | |
28 | |
29 namespace { | |
30 | |
31 const std::string g_default_sc_app_path = "/Applications/SuperCollider"; | |
32 | |
33 void PrintHelpAndQuit(const bo::options_description& options, | |
34 int exit_code = 0) { | |
35 bo::arg = "value"; | |
36 std::cout << '\n' << options << std::endl; | |
37 exit(exit_code); | |
38 } | |
39 | |
40 std::string GetTimeString() { | |
41 std::time_t raw_time; | |
42 time(&raw_time); | |
43 tm* time_info = localtime(&raw_time); | |
44 char buffer[20]; | |
45 strftime(buffer, 20, "%Y-%m-%d_%H:%M:%S", time_info); | |
46 return buffer; | |
47 } | |
48 | |
49 | |
50 } // namespace | |
51 | |
52 | |
53 void ParseCommandLine(int argument_count, | |
54 const char* arguments[], | |
55 ProgramOptions* options) { | |
56 bo::options_description description; | |
57 description.add_options() | |
58 ("help,?", "Displays this message") | |
59 ("target,t", | |
60 bo::value<std::string>(&options->target_path_)->required(), | |
61 "Target sound file path") | |
62 ("grammar,g", | |
63 bo::value<std::string>(&options->grammar_path_), | |
64 "Grammar file path") | |
65 ("scpath,s", | |
66 bo::value<std::string>(&options->sc_app_path_), | |
67 "Path to SuperCollider application folder") | |
68 ("workfolder,w", | |
69 bo::value<std::string>(&options->work_folder_), | |
70 "Path of folder to place files in") | |
71 ("population,p", | |
72 bo::value<std::size_t>(&options->population_size_)->default_value(500), | |
73 "Population size") | |
74 ("generations,G", | |
75 bo::value<std::size_t>(&options->generations_)->default_value(20), | |
76 "Number of Generations") | |
77 ("fitness,f", | |
78 bo::value<double>(&options->fitness_threshold_)->default_value(0), | |
79 "Fitness threshold") | |
80 ("tournament,T", | |
81 bo::value<std::size_t>(&options->tournament_size_)->default_value(7), | |
82 "Tournament selection size") | |
83 ("crossover,c", | |
84 bo::value<double>(&options->crossover_rate_)->default_value(0.6, "0.6"), | |
85 "Crossover rate") | |
86 ("mutation,m", | |
87 bo::value<double>(&options->mutation_rate_)->default_value(0.35, "0.35"), | |
88 "Mutation rate") | |
89 ("reproducebest,r", | |
90 bo::value<bool>(&options->reproduce_best_individual_)->default_value(false), | |
91 "Automatically reproduce best individual when populating next generation.") | |
92 ("features,F", | |
93 bo::value<std::string>(&options->fitness_features_), | |
94 "Set of features that the fitness function will measure when comparing files." | |
95 " Must be a comma separated list of feature names, which can be any of the following:" | |
96 " pitch, energy, mfccs, dmfccs, ddmfccs, mag, logmag, centroid, spread, flux." | |
97 " Default value is 'mfccs,dmfccs,ddmfccs'.") | |
98 ("windowsize,w", | |
99 bo::value<std::size_t>(&options->analysis_window_size_)->default_value(1024), | |
100 "Analysis Window Size") | |
101 ("hopsize,h", | |
102 bo::value<std::size_t>(&options->analysis_hop_size_)->default_value(256), | |
103 "Analysis Hop Size") | |
104 ("maxtreedepth,M", | |
105 bo::value<std::size_t>(&options->maximum_tree_depth_)->default_value(3), | |
106 "Maximum generated tree depth (can grow bigger through mutation).") | |
107 ("keepfolders,k", | |
108 bo::value<bool>(&options->keep_temp_folders_)->default_value(false), | |
109 "When set to 1 the temporary generation folders won't be deleted") | |
110 ("corelimit,C", | |
111 bo::value<std::size_t>(&options->core_limit_)->default_value(0), | |
112 "Limits the number of cores gpsynth will use simultaneously, 0=unlimited.") | |
113 ; | |
114 | |
115 bo::command_line_parser parser(argument_count, arguments); | |
116 parser.options(description); | |
117 bo::variables_map config; | |
118 try { | |
119 bo::store(parser.run(), config); | |
120 bo::notify(config); | |
121 } catch (std::exception& e) { | |
122 std::cout << "Error parsing options: " << e.what() << ".\n"; | |
123 PrintHelpAndQuit(description, -1); | |
124 } | |
125 | |
126 if (config.count("help")) { | |
127 PrintHelpAndQuit(description); | |
128 } | |
129 | |
130 if (config.count("workfolder") == 0) { | |
131 options->work_folder_ = bf::current_path().string(); | |
132 } | |
133 // validate the work folder path | |
134 if (!bf::is_directory(options->work_folder_)) { | |
135 std::cout << "Work folder path '" << options->work_folder_ | |
136 << "' doesn't exist.\n"; | |
137 exit(-1); | |
138 } | |
139 options->work_folder_ += "/gpsynth_" + GetTimeString() + "/"; | |
140 | |
141 if (config.count("scpath") == 0) { | |
142 options->sc_app_path_ = g_default_sc_app_path; | |
143 } | |
144 if (!bf::is_directory(options->sc_app_path_)) { | |
145 std::cout << "SC App path '" << options->sc_app_path_ | |
146 << "' doesn't exist.\n"; | |
147 exit(-1); | |
148 } | |
149 | |
150 if (options->tournament_size_ < 1) { | |
151 std::cout << "Tournament size must be greater than zero.\n"; | |
152 exit(-1); | |
153 } | |
154 | |
155 if (options->tournament_size_ > options->population_size_) { | |
156 std::cout << "Tournament size can not be larger than population size.\n"; | |
157 exit(-1); | |
158 } | |
159 | |
160 if (options->crossover_rate_ < 0 || options->crossover_rate_ > 1) { | |
161 std::cout << "The crossover rate should be between 0-1.\n"; | |
162 exit(-1); | |
163 } | |
164 | |
165 if (options->mutation_rate_ < 0 || options->mutation_rate_ > 1) { | |
166 std::cout << "The mutation rate should be between 0-1.\n"; | |
167 exit(-1); | |
168 } | |
169 | |
170 if (options->maximum_tree_depth_ < 1) { | |
171 std::cout << "Maximum tree depth must be greater than zero.\n"; | |
172 exit(-1); | |
173 } | |
174 | |
175 if (options->fitness_features_.empty()) { | |
176 options->fitness_features_ = "mfccs,dmfccs,ddmfccs"; | |
177 } | |
178 } | |
179 | |
180 |