iPlug2 - C++ Audio Plug-in Framework
IPlugParameter.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
18 #include <atomic>
19 #include <cstring>
20 #include <functional>
21 #include <memory>
22 
23 #include "wdlstring.h"
24 
25 #include "IPlugUtilities.h"
26 
27 BEGIN_IPLUG_NAMESPACE
28 
30 class IParam
31 {
32 public:
33 
35  enum EParamType { kTypeNone, kTypeBool, kTypeInt, kTypeEnum, kTypeDouble };
36 
38  enum EParamUnit { kUnitPercentage, kUnitSeconds, kUnitMilliseconds, kUnitSamples, kUnitDB, kUnitLinearGain, kUnitPan, kUnitPhase, kUnitDegrees, kUnitMeters, kUnitRate, kUnitRatio, kUnitFrequency, kUnitOctaves, kUnitCents, kUnitAbsCents, kUnitSemitones, kUnitMIDINote, kUnitMIDICtrlNum, kUnitBPM, kUnitBeats, kUnitCustom };
39 
41  enum EDisplayType { kDisplayLinear, kDisplayLog, kDisplayExp, kDisplaySquared, kDisplaySquareRoot, kDisplayCubed, kDisplayCubeRoot };
42 
44  enum EFlags
45  {
51  kFlagStepped = 0x2,
57  kFlagMeta = 0x10,
58  };
59 
61  using DisplayFunc = std::function<void(double, WDL_String&)>;
62 
63 #pragma mark - Shape
64 
66  struct Shape
67  {
68  virtual ~Shape() {}
69 
71  virtual Shape* Clone() const = 0;
72 
75  virtual void Init(const IParam& param) {}
76 
78  virtual EDisplayType GetDisplayType() const = 0;
79 
84  virtual double NormalizedToValue(double value, const IParam& param) const = 0;
85 
90  virtual double ValueToNormalized(double value, const IParam& param) const = 0;
91  };
92 
94  struct ShapeLinear : public Shape
95  {
96  Shape* Clone() const override { return new ShapeLinear(*this); }
97  IParam::EDisplayType GetDisplayType() const override { return kDisplayLinear; }
98  double NormalizedToValue(double value, const IParam& param) const override;
99  double ValueToNormalized(double value, const IParam& param) const override;
100 
101  double mShape;
102  };
103 
105  struct ShapePowCurve : public Shape
106  {
107  ShapePowCurve(double shape);
108  Shape* Clone() const override { return new ShapePowCurve(*this); }
109  IParam::EDisplayType GetDisplayType() const override;
110  double NormalizedToValue(double value, const IParam& param) const override;
111  double ValueToNormalized(double value, const IParam& param) const override;
112 
113  double mShape;
114  };
115 
117  struct ShapeExp : public Shape
118  {
119  void Init(const IParam& param) override;
120  Shape* Clone() const override { return new ShapeExp(*this); }
121  IParam::EDisplayType GetDisplayType() const override { return kDisplayLog; }
122  double NormalizedToValue(double value, const IParam& param) const override;
123  double ValueToNormalized(double value, const IParam& param) const override;
124 
125  double mMul = 1.0;
126  double mAdd = 1.0;
127  };
128 
129 #pragma mark -
130 
131  IParam();
132 
133  IParam(const IParam&) = delete;
134  IParam& operator=(const IParam&) = delete;
135 
144  void InitBool(const char* name, bool defaultValue, const char* label = "", int flags = 0, const char* group = "", const char* offText = "off", const char* onText = "on");
145 
154  void InitEnum(const char* name, int defaultValue, int nEnums, const char* label = "", int flags = 0, const char* group = "", const char* listItems = 0, ...);
155 
162  void InitEnum(const char* name, int defaultValue, const std::initializer_list<const char*>& listItems, int flags = 0, const char* group = "");
163 
172  void InitInt(const char* name, int defaultValue, int minVal, int maxVal, const char* label = "", int flags = 0, const char* group = "");
173 
186  void InitDouble(const char* name, double defaultVal, double minVal, double maxVal, double step, const char* label = "", int flags = 0, const char* group = "", const Shape& shape = ShapeLinear(), EParamUnit unit = kUnitCustom, DisplayFunc displayFunc = nullptr);
187 
196  void InitSeconds(const char* name, double defaultVal = 1., double minVal = 0., double maxVal = 10., double step = 0.1, int flags = 0, const char* group = "");
197 
206  void InitMilliseconds(const char* name, double defaultVal = 1., double minVal = 0., double maxVal = 100., int flags = 0, const char* group = "");
207 
216  void InitFrequency(const char* name, double defaultVal = 1000., double minVal = 0.1, double maxVal = 10000., double step = 0.1, int flags = 0, const char* group = "");
217 
225  void InitPitch(const char* name, int defaultVal = 60, int minVal = 0, int maxVal = 128, int flags = 0, const char* group = "", bool middleCisC4 = false);
226 
235  void InitGain(const char* name, double defaultVal = 0., double minVal = -70., double maxVal = 24., double step = 0.5, int flags = 0, const char* group = "");
236 
244  void InitPercentage(const char* name, double defaultVal = 0., double minVal = 0., double maxVal = 100., int flags = 0, const char* group = "");
245 
253  void InitAngleDegrees(const char* name, double defaultVal = 0., double minVal = 0., double maxVal = 360., int flags = 0, const char* group = "");
254 
260  void Init(const IParam& p, const char* searchStr = "", const char* replaceStr = "", const char* newGroup = "");
261 
265  double StringToValue(const char* str) const;
266 
270  inline double Constrain(double value) const
271  {
272  return Clip((mFlags & kFlagStepped ? std::round(value / mStep) * mStep : value), mMin, mMax);
273  }
274 
278  inline double ConstrainNormalized(double normalizedValue) const
279  {
280  return ToNormalized(mShape->NormalizedToValue(normalizedValue, *this));
281  }
282 
286  inline double ToNormalized(double nonNormalizedValue) const
287  {
288  return Clip(mShape->ValueToNormalized(Constrain(nonNormalizedValue), *this), 0., 1.);
289  }
290 
294  inline double FromNormalized(double normalizedValue) const
295  {
296  return Constrain(mShape->NormalizedToValue(normalizedValue, *this));
297  }
298 
301  void Set(double value) { mValue.store(Constrain(value)); }
302 
305  void SetNormalized(double normalizedValue) { Set(FromNormalized(normalizedValue)); }
306 
309  void SetString(const char* str) { mValue.store(StringToValue(str)); }
310 
312  void SetToDefault() { mValue.store(mDefault); }
313 
316  void SetDefault(double value) { mDefault = value; SetToDefault(); }
317 
321  void SetDisplayText(double value, const char* str);
322 
325  void SetDisplayPrecision(int precision);
326 
329  void SetLabel(const char* label) { strcpy(mLabel, label); }
330 
333  void SetDisplayFunc(DisplayFunc func) { mDisplayFunction = func; }
334 
337  double Value() const { return mValue.load(); }
338 
341  bool Bool() const { return (mValue.load() >= 0.5); }
342 
345  int Int() const { return static_cast<int>(mValue.load()); }
346 
351  double DBToAmp() const { return iplug::DBToAmp(mValue.load()); }
352 
355  double GetNormalized() const { return ToNormalized(mValue.load()); }
356 
360  void GetDisplay(WDL_String& display, bool withDisplayText = true) const { GetDisplay(mValue.load(), false, display, withDisplayText); }
361 
367  void GetDisplay(double value, bool normalized, WDL_String& display, bool withDisplayText = true) const;
368 
372  void GetDisplayWithLabel(WDL_String& display, bool withDisplayText = true) const
373  {
374  GetDisplay(mValue.load(), false, display, withDisplayText);
375  const char* hostlabel = GetLabel();
376  if (CStringHasContents(hostlabel))
377  {
378  display.Append(" ");
379  display.Append(hostlabel);
380  }
381  }
382 
385  const char* GetName() const;
386 
389  const char* GetLabel() const;
390 
393  const char* GetGroup() const;
394 
397  const char* GetCustomUnit() const { return mUnit == kUnitCustom ? mLabel : nullptr; }
398 
401  int NDisplayTexts() const;
402 
406  const char* GetDisplayText(double value) const;
407 
412  const char* GetDisplayTextAtIdx(int idx, double* pValue = nullptr) const;
413 
418  bool MapDisplayText(const char* str, double* pValue) const;
419 
423  EParamType Type() const { return mType; }
424 
428  EParamUnit Unit() const { return mUnit; }
429 
433  EDisplayType DisplayType() const { return mShape->GetDisplayType(); }
434 
438  double GetDefault(bool normalized = false) const { return normalized ? ToNormalized(GetDefault()) : mDefault; }
439 
442  double GetMin() const { return mMin; }
443 
446  double GetMax() const { return mMax; }
447 
451  void GetBounds(double& lo, double& hi) const;
452 
455  double GetRange() const { return mMax - mMin; }
456 
459  double GetStep() const { return mStep; }
460 
463  int GetDisplayPrecision() const {return mDisplayPrecision;}
464 
467  int GetFlags() const { return mFlags; }
468 
470  bool GetCanAutomate() const { return !(mFlags & kFlagCannotAutomate); }
471 
473  bool GetStepped() const { return mFlags & kFlagStepped; }
474 
476  bool GetNegateDisplay() const { return mFlags & kFlagNegateDisplay; }
477 
479  bool GetSignDisplay() const { return mFlags & kFlagSignDisplay; }
480 
482  bool GetMeta() const { return mFlags & kFlagMeta; }
483 
487  void GetJSON(WDL_String& json, int idx) const;
488 
490  void PrintDetails() const;
491 private:
493  struct DisplayText
494  {
495  double mValue;
496  char mText[MAX_PARAM_DISPLAY_LEN];
497  };
498 
499  EParamType mType = kTypeNone;
500  EParamUnit mUnit = kUnitCustom;
501  std::atomic<double> mValue{0.0};
502  double mMin = 0.0;
503  double mMax = 1.0;
504  double mStep = 1.0;
505  double mDefault = 0.0;
506  int mDisplayPrecision = 0;
507  int mFlags = 0;
508 
509  char mName[MAX_PARAM_NAME_LEN];
510  char mLabel[MAX_PARAM_LABEL_LEN];
511  char mParamGroup[MAX_PARAM_GROUP_LEN];
512 
513  std::unique_ptr<Shape> mShape;
514  DisplayFunc mDisplayFunction = nullptr;
515 
516  WDL_TypedBuf<DisplayText> mDisplayTexts;
517 } WDL_FIXALIGN;
518 
519 END_IPLUG_NAMESPACE
Indicates that the parameter should be displayed as a signed value.
void InitSeconds(const char *name, double defaultVal=1., double minVal=0., double maxVal=10., double step=0.1, int flags=0, const char *group="")
Initialize the parameter as seconds.
void InitPitch(const char *name, int defaultVal=60, int minVal=0, int maxVal=128, int flags=0, const char *group="", bool middleCisC4=false)
Initialize the parameter as pitch.
Utility functions and macros.
bool GetStepped() const
const char * GetName() const
Returns the parameter&#39;s name.
int NDisplayTexts() const
Get the number of display texts for the parameter.
Shape * Clone() const override
const char * GetCustomUnit() const
Get parameter&#39;s label (unit suffix)
void SetString(const char *str)
Set the parameter value using a textual representation.
void Set(double value)
Sets the parameter value.
virtual double ValueToNormalized(double value, const IParam &param) const =0
Returns the normalized value from a real value, based on an IParam&#39;s settings.
void GetJSON(WDL_String &json, int idx) const
Get a JSON description of the parameter.
void InitMilliseconds(const char *name, double defaultVal=1., double minVal=0., double maxVal=100., int flags=0, const char *group="")
Initialize the parameter as milliseconds.
void SetDefault(double value)
Set the parameter&#39;s default value, and set the parameter to that default.
IParam::EDisplayType GetDisplayType() const override
bool GetSignDisplay() const
IPlug&#39;s parameter class.
const char * GetDisplayText(double value) const
Get the display text for a particular value.
int GetDisplayPrecision() const
Returns the parameter&#39;s precision.
double ConstrainNormalized(double normalizedValue) const
Constrains a normalised input value similarly to Constrain()
Exponential parameter shaping.
EParamUnit Unit() const
Get the parameter&#39;s unit.
double GetRange() const
Returns the parameter&#39;s range.
bool Bool() const
Returns the parameter&#39;s value as a boolean.
Base struct for parameter shaping.
double DBToAmp() const
Gain based on parameter&#39;s current value in dB.
double Value() const
Gets a readable value of the parameter.
void InitPercentage(const char *name, double defaultVal=0., double minVal=0., double maxVal=100., int flags=0, const char *group="")
Initialize the parameter as percentage.
Indicates that the parameter may influence the state of other parameters.
double GetMin() const
Returns the parameter&#39;s minimum value.
void InitFrequency(const char *name, double defaultVal=1000., double minVal=0.1, double maxVal=10000., double step=0.1, int flags=0, const char *group="")
Initialize the parameter as frequency.
double FromNormalized(double normalizedValue) const
Convert a normalized value to real value for this parameter.
bool GetCanAutomate() const
double StringToValue(const char *str) const
Convert a textual representation of the parameter value to a double (real value)
double GetMax() const
Returns the parameter&#39;s maximum value.
Indicates that the parameter is not automatable.
Shape * Clone() const override
double GetNormalized() const
Returns the parameter&#39;s normalized value.
std::function< void(double, WDL_String &)> DisplayFunc
DisplayFunc allows custom parameter display functions, defined by a lambda matching this signature...
void SetNormalized(double normalizedValue)
Sets the parameter value from a normalized range (usually coming from the linked IControl) ...
int GetFlags() const
Returns the parameter&#39;s flags.
Shape * Clone() const override
void InitEnum(const char *name, int defaultValue, int nEnums, const char *label="", int flags=0, const char *group="", const char *listItems=0,...)
Initialize the parameter as an enumerated list.
IParam::EDisplayType GetDisplayType() const override
double GetDefault(bool normalized=false) const
Returns the parameter&#39;s default value.
const char * GetGroup() const
Returns the parameter&#39;s group.
void SetDisplayFunc(DisplayFunc func)
Set the function to translate display values.
void SetLabel(const char *label)
Set the parameters label after creation.
void GetDisplay(WDL_String &display, bool withDisplayText=true) const
Get the current textual display for the current parameter value.
const char * GetLabel() const
Returns the parameter&#39;s label.
virtual EDisplayType GetDisplayType() const =0
virtual double NormalizedToValue(double value, const IParam &param) const =0
Returns the real value from a normalized input, based on an IParam&#39;s settings.
int Int() const
Returns the parameter&#39;s value as an integer.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
void PrintDetails() const
Helper to print the parameter details to debug console in debug builds.
EParamUnit
Used by AudioUnit plugins to determine the appearance of parameters, based on the kind of data they r...
EFlags
Flags to determine characteristics of the parameter.
virtual void Init(const IParam &param)
Initializes the shape instance.
PowCurve parameter shaping.
double ToNormalized(double nonNormalizedValue) const
Convert a real value to normalized value for this parameter.
static double DBToAmp(double dB)
Calculates gain from a given dB value.
Indicates that the parameter should be displayed as a negative value.
EParamType Type() const
Get the parameter&#39;s type.
void InitBool(const char *name, bool defaultValue, const char *label="", int flags=0, const char *group="", const char *offText="off", const char *onText="on")
Initialize the parameter as boolean.
void SetDisplayPrecision(int precision)
Set the parameters display precision.
void GetDisplayWithLabel(WDL_String &display, bool withDisplayText=true) const
Fills the WDL_String the value of the parameter along with the label, e.g.
Indicates that the parameter is stepped.
void InitInt(const char *name, int defaultValue, int minVal, int maxVal, const char *label="", int flags=0, const char *group="")
Initialize the parameter as integer.
EDisplayType DisplayType() const
Get the parameter&#39;s display type.
void InitGain(const char *name, double defaultVal=0., double minVal=-70., double maxVal=24., double step=0.5, int flags=0, const char *group="")
Initialize the parameter as gain (units in decibels)
void InitAngleDegrees(const char *name, double defaultVal=0., double minVal=0., double maxVal=360., int flags=0, const char *group="")
Initialize the parameter as angle in degrees.
EParamType
Defines types or parameter.
bool GetNegateDisplay() const
Linear parameter shaping.
void InitDouble(const char *name, double defaultVal, double minVal, double maxVal, double step, const char *label="", int flags=0, const char *group="", const Shape &shape=ShapeLinear(), EParamUnit unit=kUnitCustom, DisplayFunc displayFunc=nullptr)
Initialize the parameter as double.
bool MapDisplayText(const char *str, double *pValue) const
Get the value of a particular display text.
virtual Shape * Clone() const =0
double GetStep() const
Returns the parameter&#39;s step size.
EDisplayType
Used by AudioUnit plugins to determine the mapping of parameters.
void GetBounds(double &lo, double &hi) const
Get the minimum and maximum real value of the parameter&#39;s range in one method call.
void SetToDefault()
Replaces the parameter&#39;s current value with the default one.
void SetDisplayText(double value, const char *str)
Set some text to display for a particular value, e.g.
bool GetMeta() const
const char * GetDisplayTextAtIdx(int idx, double *pValue=nullptr) const
Get the display text at a particular index.
double Constrain(double value) const
Constrains the input value between mMin and mMax and apply stepping if relevant.