Essentia  2.1-beta5-dev
algorithmfactory_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2016 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef ESSENTIA_ALGORITHMFACTORY_CPP
21 #define ESSENTIA_ALGORITHMFACTORY_CPP
22 
23 namespace essentia {
24 
25 template <typename BaseAlgorithm>
27  if (!_instance) {
28  throw EssentiaException("You haven't initialized the factory yet... Please do it now!");
29  }
30  return *_instance;
31 }
32 
33 template <typename BaseAlgorithm>
34 std::vector<std::string> EssentiaFactory<BaseAlgorithm>::keys() {
35  std::vector<std::string> result;
36  const CreatorMap& m = instance()._map;
37  for (typename CreatorMap::const_iterator it = m.begin(); it != m.end(); ++it) {
38  result.push_back(it->first);
39  }
40  return result;
41 }
42 
43 template <typename BaseAlgorithm>
44 BaseAlgorithm* EssentiaFactory<BaseAlgorithm>::create_i(const std::string& id) const {
45  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Creating algorithm: " << id);
46 
47  typename CreatorMap::const_iterator it = _map.find(id);
48  if (it == _map.end()) {
49  std::ostringstream msg;
50  msg << "Identifier '" << id << "' not found in registry...\n";
51  msg << "Available algorithms:";
52  for (it=_map.begin(); it!=_map.end(); ++it) {
53  msg << ' ' << it->first;
54  }
55  throw EssentiaException(msg);
56  }
57 
59  BaseAlgorithm* algo = it->second.create();
61 
62  // adds the name of the algorithm to itself so it knows it.
63  algo->setName(id);
64 
65  // declare the acceptable parameters for this algorithm. It would be nicer to
66  // have this automatically done in the Configurable constructor, but we cannot
67  // call abstract virtual functions from the base constructor.
68  algo->declareParameters();
69 
70  // configure with default parameters to ensure we're not in an undefined state.
71  // This should never throw an exception. If it does, explain why it should
72  // absolutely be fixed.
73  try {
74  // default parameters should have been filled by the call to declareParameters
75  // from the constructor, so there is no need to make a copy of them, just call
76  // arg-less version of configure()
77  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Configuring " << id << " with default parameters");
78  algo->configure();
79  }
80  catch (EssentiaException& e) {
81  // We should never arrive here, because it means that we can have algorithms
82  // which are not configured at all, hence in an invalid state. This cannot
83  // happen, hence the message explaining why and we rethrow the exception.
84  std::ostringstream msg;
85  msg << "ERROR: Algorithm " << id << " could not be configured using default values.\n"
86  << " If it doesn't make sense for an algorithm to be configured with\n"
87  << " default values, then it should still be able to be instantiated, and\n"
88  << " it is your responsibility to keep track of the fact that it should\n"
89  << " currently be impossible to call it (for example, by checking if the state\n"
90  << " is valid upon entering the process() method).\n\n"
91  << e.what();
92  throw EssentiaException(msg);
93  }
94 
95  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Creating " << id << " ok!");
96 
97  return algo;
98 }
99 
100 
101 #define CREATE_I template <typename BaseAlgorithm> BaseAlgorithm* EssentiaFactory<BaseAlgorithm>::create_i(const std::string& id
102 #define P(n) , const std::string& name##n, const Parameter& value##n
103 #define AP(n) params.add(name##n, value##n);
104 
105 #define CREATE_I_BEG ) const { \
106  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Creating algorithm: " << id); \
107  typename CreatorMap::const_iterator it = _map.find(id); \
108  if (it == _map.end()) { \
109  std::ostringstream msg; \
110  msg << "Identifier '" << id << "' not found in registry...\n"; \
111  msg << "Available algorithms:"; \
112  for (it=_map.begin(); it!=_map.end(); ++it) { \
113  msg << ' ' << it->first; \
114  } \
115  throw EssentiaException(msg); \
116  } \
117  E_DEBUG_INDENT; \
118  BaseAlgorithm* algo = it->second.create(); \
119  E_DEBUG_OUTDENT; \
120  algo->setName(id); \
121  algo->declareParameters(); \
122  ParameterMap params;
123 
124 #define CREATE_I_END \
125  algo->setParameters(params); \
126  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Configuring " << id << " with default parameters"); \
127  algo->configure(); \
128  E_DEBUG(EFactory, BaseAlgorithm::processingMode << ": Creating " << id << " ok!"); \
129  return algo; \
130 }
131 
132 
136 CREATE_I P(1) P(2) P(3) P(4) CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) CREATE_I_END
137 CREATE_I P(1) P(2) P(3) P(4) P(5) CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) CREATE_I_END
138 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) CREATE_I_END
139 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7)
140  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) CREATE_I_END
141 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8)
142  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) CREATE_I_END
143 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9)
144  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) CREATE_I_END
145 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10)
146  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) CREATE_I_END
147 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11)
148  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) CREATE_I_END
149 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11) P(12)
150  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) AP(12) CREATE_I_END
151 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11) P(12) P(13)
152  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) AP(12) AP(13) CREATE_I_END
153 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11) P(12) P(13) P(14)
154  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) AP(12) AP(13) AP(14) CREATE_I_END
155 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11) P(12) P(13) P(14) P(15)
156  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) AP(12) AP(13) AP(14) AP(15) CREATE_I_END
157 CREATE_I P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) P(10) P(11) P(12) P(13) P(14) P(15) P(16)
158  CREATE_I_BEG AP(1) AP(2) AP(3) AP(4) AP(5) AP(6) AP(7) AP(8) AP(9) AP(10) AP(11) AP(12) AP(13) AP(14) AP(15) AP(16) CREATE_I_END
159 
160 
161 #undef CREATE_I_END
162 #undef CREATE_I_BODY
163 #undef AP
164 #undef P
165 #undef CREATE_I
166 
167 } // namespace essentia
168 
169 #endif // ESSENTIA_ALGORITHMFACTORY_CPP
virtual const char * what() const
Definition: types.h:99
BaseAlgorithm * create_i(const std::string &id) const
Definition: algorithmfactory_impl.h:44
#define E_DEBUG_OUTDENT
Definition: debugging.h:149
#define E_DEBUG_INDENT
Definition: debugging.h:148
#define CREATE_I
Definition: algorithmfactory_impl.h:101
#define CREATE_I_END
Definition: algorithmfactory_impl.h:124
static std::vector< std::string > keys()
Definition: algorithmfactory_impl.h:34
Definition: algorithmfactory.h:58
Definition: algorithm.h:28
#define P(n)
Definition: algorithmfactory_impl.h:102
Definition: types.h:76
#define CREATE_I_BEG
Definition: algorithmfactory_impl.h:105
#define E_DEBUG(module, msg)
Definition: debugging.h:157
static EssentiaFactory & instance()
Definition: algorithmfactory_impl.h:26
Definition: debugging.h:44
#define AP(n)
Definition: algorithmfactory_impl.h:103