ape  0.5.0
Audio Programming Environment
parameter.h
Go to the documentation of this file.
1 #ifndef CPPAPE_PARAMETER_H
2 #define CPPAPE_PARAMETER_H
3 
4 #include "baselib.h"
5 #include <cmath>
6 #include <string>
7 #include <string_view>
8 #include <atomic>
9 #include <initializer_list>
10 
11 namespace ape
12 {
26  template<class Type, typename Select = std::true_type>
27  class Param;
28 
29  namespace
30  {
31  static PFloat scaleLin(PFloat x, PFloat mi, PFloat ma)
32  {
33  return mi + x * (ma - mi);
34  }
35 
36  static PFloat scaleExp(PFloat x, PFloat mi, PFloat ma)
37  {
38  return mi * std::pow(ma / mi, x);
39  }
40 
41  static PFloat scaleLinQ(PFloat x, PFloat mi, PFloat ma)
42  {
43  return std::floor(static_cast<PFloat>(0.5) + mi + x * (ma - mi));
44  }
45 
46  static PFloat scaleExpQ(PFloat x, PFloat mi, PFloat ma)
47  {
48  return std::floor(static_cast<PFloat>(0.5) + mi * std::pow(ma / mi, x));
49  }
50 
51  // inverted
52 
53  static PFloat invScaleLin(PFloat y, PFloat mi, PFloat ma)
54  {
55  return (y - mi) / (ma - mi);
56  }
57 
58  static PFloat invScaleExp(PFloat y, PFloat mi, PFloat ma)
59  {
60  return std::log(y / mi) / std::log(ma / mi);
61  }
62 
63  static PFloat invScaleLinQ(PFloat y, PFloat mi, PFloat ma)
64  {
65  return (std::floor(static_cast<PFloat>(0.5) + y) - mi) / (ma - mi);
66  }
67 
68  static PFloat invScaleExpQ(PFloat y, PFloat mi, PFloat ma)
69  {
70  return std::log(std::floor(static_cast<PFloat>(0.5) + y) / mi) / std::log(ma / mi);
71  }
72  }
73 
78  class Range
79  {
80  template<class Type, typename Select>
81  friend class Param;
82 
83  public:
84 
88  enum Mapping
89  {
93  Lin,
101  };
102 
107  : min(0), max(1), mapping(Lin)
108  {
109 
110  }
111 
115  Range(PFloat minValue, PFloat maxValue, Mapping parameterMapping = Lin)
116  : min(minValue), max(maxValue), mapping(parameterMapping)
117  {
118  if (parameterMapping == Exp)
119  {
120  assert(minValue != 0 && "Exponential mapping cannot have a minimum of 0");
121  assert(maxValue != 0 && "Exponential mapping cannot have a maximum of 0");
122  }
123  }
124 
129  PFloat operator()(PFloat value) const noexcept
130  {
131  if (mapping == Lin)
132  return min + value * (max - min);
133  else
134  return min * pow(max / min, value);
135  }
136 
144  PFloat inverse(bool quantized, PFloat value) const noexcept
145  {
146  return getNormalizer(quantized)(value, min, max);
147  }
148 
155  APE_Transformer getTransformer(bool quantized) const noexcept
156  {
157  return !quantized ? (mapping == Lin ? scaleLin : scaleExp) : (mapping == Lin ? scaleLinQ : scaleExpQ);
158  }
159 
166  APE_Normalizer getNormalizer(bool quantized) const noexcept
167  {
168  return !quantized ? (mapping == Lin ? invScaleLin : invScaleExp) : (mapping == Lin ? invScaleLinQ : invScaleExpQ);
169  }
170 
174  auto getMapping() const noexcept { return mapping; }
178  auto getMin() const noexcept { return min; }
182  auto getMax() const noexcept { return max; }
183 
184  private:
185 
186  const PFloat min, max;
187  const Mapping mapping;
188  };
189 
203  template<class Type, class Derived>
204  class ParameterBase : public UIObject
205  {
206  protected:
207 
211  ParameterBase(const std::string_view paramName = "", const Range parameterRange = Range())
212  : name(paramName.size() == 0 ? "Unnamed" : paramName)
213  , range(parameterRange)
214  {
215  }
216 
217  public:
218 
223  static Type convert(PFloat normalized) noexcept
224  {
225  return Derived::convert(normalized);
226  }
227 
232  static PFloat representationFor(Type value) noexcept
233  {
234  return Derived::representationFor(value);
235  }
236 
240  int id() const noexcept
241  {
242  return param.id;
243  }
244 
252  bool changed() const noexcept
253  {
254  return param.changeFlags != 0;
255  }
256 
263  operator Type() const noexcept
264  {
265  return convert(range(param.next));
266  }
267 
271  template<typename Index>
272  Type operator [] (Index idx) const noexcept
273  {
274  return at(idx);
275  }
276 
284  template<typename Index>
285  Type at(Index idx) const noexcept
286  {
287  return convert(range(param.old + param.step * idx));
288  }
289 
296  Derived& operator = (Type t) noexcept
297  {
298  param.next = range.inverse(false, Derived::representationFor(t));
299  return static_cast<Derived&>(*this);
300  }
301 
306  {
307  getInterface().destroyResource(&getInterface(), param.id, -1);
308  }
309 
313  auto getRange() const noexcept { return range; }
314 
315  protected:
316 
318  const Range range;
319  std::string name;
320  };
321 
326  template<>
327  class Param<bool> : public ParameterBase<bool, Param<bool>>
328  {
329  public:
331  typedef bool ParameterType;
332 
333  using Base::operator =;
334 
335  Param(const std::string_view paramName = "", const Range parameterRange = Range())
336  : Param(paramName, "", parameterRange)
337  {
338 
339  }
340 
341  Param(const std::string_view paramName, const std::string& unit, const Range parameterRange = Range())
342  : Base(paramName, parameterRange)
343  {
344  getInterface().createBooleanParameter(&getInterface(), this->name.c_str(), &this->param);
345  }
346 
347  static ParameterType convert(PFloat value) noexcept
348  {
349  return static_cast<int>(std::floor((value + static_cast<PFloat>(0.5f)))) ? true : false;
350  }
351 
352  static PFloat representationFor(ParameterType value) noexcept
353  {
354  return static_cast<PFloat>(value ? 1.0f : 0.0f);
355  }
356  };
357 
363  template<typename T>
364  class Param<T, typename std::is_enum<T>::type> : public ParameterBase<T, Param<T>>
365  {
366  public:
368  typedef T ParameterType;
384  typedef std::initializer_list<const char*> Names;
385  using Base::operator =;
386 
404  Param(const std::string_view paramName, const std::initializer_list<const char*> values)
405  : Base(paramName, Range(0, values.size() - 1))
406  {
407  getInterface().createListParameter(
408  &getInterface(),
409  this->name.c_str(),
410  &this->param,
411  values.size(),
412  values.begin()
413  );
414  }
415 
416  static ParameterType convert(PFloat value) noexcept
417  {
418  return static_cast<ParameterType>(std::round(value));
419  }
420 
421  static PFloat representationFor(ParameterType value) noexcept
422  {
423  return static_cast<float>(value);
424  }
425  };
426 
431  template<>
432  class Param<float> : public ParameterBase<float, Param<float>>
433  {
434  public:
436  typedef float ParameterType;
437 
438  using Base::operator =;
439 
440  Param(const std::string_view paramName = "", const Range parameterRange = Range())
441  : Param(paramName, "", parameterRange)
442  {
443 
444  }
445 
446  Param(const std::string_view paramName, const std::string& unit, const Range parameterRange = Range())
447  : Base(paramName, parameterRange)
448  {
449  getInterface().createNormalParameter(
450  &getInterface(),
451  this->name.c_str(),
452  unit.c_str(),
453  &this->param,
454  this->range.getTransformer(false),
455  this->range.getNormalizer(false),
456  this->range.min,
457  this->range.max
458  );
459  }
460 
461  static constexpr ParameterType convert(PFloat value) noexcept
462  {
463  return static_cast<ParameterType>(value);
464  }
465 
466  static constexpr PFloat representationFor(ParameterType value) noexcept
467  {
468  return static_cast<PFloat>(value);
469  }
470  };
471 
476  template<>
477  class Param<double> : public ParameterBase<double, Param<double>>
478  {
479  public:
481  typedef double ParameterType;
482 
483  using Base::operator =;
484 
485  Param(const std::string_view paramName = "", const Range parameterRange = Range())
486  : Param(paramName, "", parameterRange)
487  {
488 
489  }
490 
491  Param(const std::string_view paramName, const std::string& unit, const Range parameterRange = Range())
492  : Base(paramName, parameterRange)
493  {
494  getInterface().createNormalParameter(
495  &getInterface(),
496  this->name.c_str(),
497  unit.c_str(),
498  &this->param,
499  this->range.getTransformer(false),
500  this->range.getNormalizer(false),
501  this->range.min,
502  this->range.max
503  );
504  }
505 
506  static constexpr ParameterType convert(PFloat value) noexcept
507  {
508  return static_cast<ParameterType>(value);
509  }
510 
511  static constexpr PFloat representationFor(ParameterType value) noexcept
512  {
513  return static_cast<PFloat>(value);
514  }
515 
516  };
517 
524  template<>
525  class Param<int> : public ParameterBase<int, Param<int>>
526  {
527  public:
529  typedef int ParameterType;
530 
531  using Base::operator =;
532 
533  Param(const std::string_view paramName = "", const Range parameterRange = Range())
534  : Param(paramName, "", parameterRange)
535  {
536 
537  }
538 
539  Param(const std::string_view paramName, const std::string& unit, const Range parameterRange = Range())
540  : Base(paramName, parameterRange)
541  {
542  getInterface().createNormalParameter(
543  &getInterface(),
544  this->name.c_str(),
545  unit.c_str(),
546  &this->param,
547  this->range.getTransformer(true),
548  this->range.getNormalizer(true),
549  this->range.min,
550  this->range.max
551  );
552  }
553 
554  static ParameterType convert(PFloat value) noexcept
555  {
556  return static_cast<ParameterType>(std::round(value));
557  }
558 
559  static constexpr PFloat representationFor(ParameterType value) noexcept
560  {
561  return static_cast<PFloat>(value);
562  }
563  };
564 
565 }
566 #endif
ape::getInterface
APE_SharedInterface & getInterface()
Acquire the low-level C API.
APE_Parameter::step
PFloat step
Definition: SharedInterface.h:93
APE_SharedInterface::min
const char const char APE_Parameter APE_Transformer APE_Normalizer PFloat min
Definition: SharedInterface.h:178
ape::Param< double >::representationFor
static constexpr PFloat representationFor(ParameterType value) noexcept
Definition: parameter.h:511
ape::ParameterBase::representationFor
static PFloat representationFor(Type value) noexcept
Convert a native Type to an engine PFloat type. convert
Definition: parameter.h:232
APE_Parameter::id
int id
Definition: SharedInterface.h:94
APE_SharedInterface::size
APE_DataType size_t size
Definition: SharedInterface.h:183
ape::Param< float >::Param
Param(const std::string_view paramName="", const Range parameterRange=Range())
Definition: parameter.h:440
ape::Param< int >::ParameterType
int ParameterType
Definition: parameter.h:529
APE_Parameter::changeFlags
int changeFlags
Definition: SharedInterface.h:94
ape::Param< float >::ParameterType
float ParameterType
Definition: parameter.h:436
ape::Param< bool >::convert
static ParameterType convert(PFloat value) noexcept
Definition: parameter.h:347
ape::Param< double >::convert
static constexpr ParameterType convert(PFloat value) noexcept
Definition: parameter.h:506
ape::ParameterBase::operator[]
Type operator[](Index idx) const noexcept
Alias for at().
Definition: parameter.h:272
ape::Param< float >::representationFor
static constexpr PFloat representationFor(ParameterType value) noexcept
Definition: parameter.h:466
APE_Normalizer
PFloat(APE_API * APE_Normalizer)(PFloat y, PFloat _min, PFloat _max)
Definition: APE.h:59
ape::Param< T, typename std::is_enum< T >::type >::convert
static ParameterType convert(PFloat value) noexcept
Definition: parameter.h:416
ape::Param< float >::Param
Param(const std::string_view paramName, const std::string &unit, const Range parameterRange=Range())
Definition: parameter.h:446
ape::Param< int >::Param
Param(const std::string_view paramName, const std::string &unit, const Range parameterRange=Range())
Definition: parameter.h:539
ape::Param< bool >::ParameterType
bool ParameterType
Definition: parameter.h:331
ape::Param< int >::convert
static ParameterType convert(PFloat value) noexcept
Definition: parameter.h:554
ape::Param< bool >::representationFor
static PFloat representationFor(ParameterType value) noexcept
Definition: parameter.h:352
ape::Range::getMax
auto getMax() const noexcept
Returns the maximum of the constructed range
Definition: parameter.h:182
ape::UIObject
Base traits class for all classes that are displayed in the GUI.
Definition: baselib.h:62
ape::Range::operator()
PFloat operator()(PFloat value) const noexcept
Evaluate the range as a f(x) function, where value is x inverse()
Definition: parameter.h:129
ape::Param< bool >::Param
Param(const std::string_view paramName="", const Range parameterRange=Range())
Definition: parameter.h:335
ape::Range::Exp
Maps exponentially from min to max.
Definition: parameter.h:100
ape::Param< bool >::Base
ParameterBase< bool, Param< bool > > Base
Definition: parameter.h:330
ape::Range::getMin
auto getMin() const noexcept
return the minimum of the constructed range
Definition: parameter.h:178
ape::Range::getMapping
auto getMapping() const noexcept
Returns the Mapping this range was constructed with
Definition: parameter.h:174
APE_Parameter::old
PFloat old
Definition: SharedInterface.h:93
ape::Range::Range
Range()
Construct a default linear range from 0 to 1
Definition: parameter.h:106
ape::ParameterBase::at
Type at(Index idx) const noexcept
Evaluate the value of the parameter at at a specific sample index, where 0 equals the start of the pr...
Definition: parameter.h:285
PFloat
double PFloat
Floating-precision point type used for parameter processing
Definition: APE.h:56
ape::Param< double >::Base
ParameterBase< double, Param< double > > Base
Definition: parameter.h:480
ape::Param< int >::representationFor
static constexpr PFloat representationFor(ParameterType value) noexcept
Definition: parameter.h:559
ape::ParameterBase::ParameterBase
ParameterBase(const std::string_view paramName="", const Range parameterRange=Range())
Constructs a named parameter.
Definition: parameter.h:211
ape::Param< bool >::Param
Param(const std::string_view paramName, const std::string &unit, const Range parameterRange=Range())
Definition: parameter.h:341
ape::ParameterBase::operator=
Derived & operator=(Type t) noexcept
Assign a value to this parameter. Depending on host support, this might only make sense inside the co...
Definition: parameter.h:296
ape::ParameterBase::convert
static Type convert(PFloat normalized) noexcept
Convert an engine PFloat to the native Type of this parameter. representationFor
Definition: parameter.h:223
ape::Range::inverse
PFloat inverse(bool quantized, PFloat value) const noexcept
Normalizes value back to a 0 .. 1 range. operator()()
Definition: parameter.h:144
ape
Definition: audiofile.h:7
ape::Param< int >::Param
Param(const std::string_view paramName="", const Range parameterRange=Range())
Definition: parameter.h:533
ape::ParameterBase
Shared functionality for all specializations of parameters. ParameterBase
Definition: parameter.h:204
ape::Param
Template for parameter specializations on different types. Parameters are based on an normalized PFlo...
Definition: parameter.h:27
ape::ParameterBase::changed
bool changed() const noexcept
Whether the parameter has changed in this processing frame. Only sensible when called from within Pro...
Definition: parameter.h:252
ape::ParameterBase::id
int id() const noexcept
A unique identifier for this parameter
Definition: parameter.h:240
ape::ParameterBase::~ParameterBase
~ParameterBase()
Delete this parameter instance.
Definition: parameter.h:305
ape::Range::getTransformer
APE_Transformer getTransformer(bool quantized) const noexcept
Retrieve a function pointer with appropriate Mapping and selectively quantized .
Definition: parameter.h:155
ape::Param< double >::Param
Param(const std::string_view paramName="", const Range parameterRange=Range())
Definition: parameter.h:485
APE_Parameter::next
PFloat next
Definition: SharedInterface.h:93
ape::ParameterBase::getRange
auto getRange() const noexcept
Returns the Range this parameter was constructed with.
Definition: parameter.h:313
ape::ParameterBase::param
APE_Parameter param
Definition: parameter.h:317
ape::ParameterBase::name
std::string name
Definition: parameter.h:319
baselib.h
ape::Param< T, typename std::is_enum< T >::type >::representationFor
static PFloat representationFor(ParameterType value) noexcept
Definition: parameter.h:421
ape::Param< float >::Base
ParameterBase< float, Param< float > > Base
Definition: parameter.h:435
ape::Param< T, typename std::is_enum< T >::type >::Base
ParameterBase< T, Param< T > > Base
Definition: parameter.h:367
ape::ParameterBase::range
const Range range
Definition: parameter.h:318
APE_Transformer
PFloat(APE_API * APE_Transformer)(PFloat x, PFloat _min, PFloat _max)
Definition: APE.h:58
ape::Param< T, typename std::is_enum< T >::type >::Names
std::initializer_list< const char * > Names
A list-initialization type suitable for a string names of enumerations, e.g.: enum class FilterChoice...
Definition: parameter.h:384
ape::Param< T, typename std::is_enum< T >::type >::Param
Param(const std::string_view paramName, const std::initializer_list< const char * > values)
Construct a parameter that can automate a list of string values, and convert them to T .
Definition: parameter.h:404
ape::Param< float >::convert
static constexpr ParameterType convert(PFloat value) noexcept
Definition: parameter.h:461
ape::Param< double >::Param
Param(const std::string_view paramName, const std::string &unit, const Range parameterRange=Range())
Definition: parameter.h:491
APE_Parameter
Definition: SharedInterface.h:91
ape::Param< int >::Base
ParameterBase< int, Param< int > > Base
Definition: parameter.h:528
ape::Range::Range
Range(PFloat minValue, PFloat maxValue, Mapping parameterMapping=Lin)
Constructs a range from minValue to maxValue with parameterMapping mapping.
Definition: parameter.h:115
ape::Range::Mapping
Mapping
Different curve mappings for the interval
Definition: parameter.h:88
ape::Range::Lin
Maps linearly from min to max
Definition: parameter.h:93
ape::Range
Represents a mapping function in a interval, suitable for evaluation between 0 .. 1 inclusive,...
Definition: parameter.h:78
ape::Param< double >::ParameterType
double ParameterType
Definition: parameter.h:481
ape::Param< T, typename std::is_enum< T >::type >::ParameterType
T ParameterType
Definition: parameter.h:368
ape::Range::getNormalizer
APE_Normalizer getNormalizer(bool quantized) const noexcept
Retrieve a function pointer with appropriate Mapping and selectively quantized , for inverse transfor...
Definition: parameter.h:166