22 using namespace iplug;
28 return param.mMin + value * (param.mMax - param.mMin);
33 return (value - param.mMin) / (param.mMax - param.mMin);
36 IParam::ShapePowCurve::ShapePowCurve(
double shape)
43 if (mShape > 2.5)
return kDisplayCubeRoot;
44 if (mShape > 1.5)
return kDisplaySquareRoot;
45 if (mShape < (2.0 / 5.0))
return kDisplayCubed;
46 if (mShape < (2.0 / 3.0))
return kDisplaySquared;
48 return IParam::kDisplayLinear;
58 return std::pow((value - param.
GetMin()) / (param.
GetMax() - param.
GetMin()), 1.0 / mShape);
63 double min = param.
GetMin();
69 mMul = std::log(param.
GetMax() / min);
74 return std::exp(mAdd + value * mMul);
79 return (std::log(value) - mAdd) / mMul;
86 mShape = std::make_unique<ShapeLinear>();
87 memset(mName, 0, MAX_PARAM_NAME_LEN *
sizeof(
char));
88 memset(mLabel, 0, MAX_PARAM_LABEL_LEN *
sizeof(
char));
89 memset(mParamGroup, 0, MAX_PARAM_LABEL_LEN *
sizeof(
char));
92 void IParam::InitBool(
const char* name,
bool defaultVal,
const char* label,
int flags,
const char* group,
const char* offText,
const char* onText)
94 if (mType == kTypeNone) mType = kTypeBool;
96 InitEnum(name, (defaultVal ? 1 : 0), 2, label, flags | kFlagStepped, group);
98 SetDisplayText(0, offText);
99 SetDisplayText(1, onText);
102 void IParam::InitEnum(
const char* name,
int defaultVal,
int nEnums,
const char* label,
int flags,
const char* group,
const char* listItems, ...)
104 if (mType == kTypeNone) mType = kTypeEnum;
106 InitInt(name, defaultVal, 0, nEnums - 1, label, flags | kFlagStepped, group);
110 SetDisplayText(0, listItems);
113 va_start(args, listItems);
114 for (
auto i = 1; i < nEnums; ++i)
115 SetDisplayText(i, va_arg(args,
const char*));
120 void IParam::InitEnum(
const char* name,
int defaultVal,
const std::initializer_list<const char*>& listItems,
int flags,
const char* group)
122 if (mType == kTypeNone) mType = kTypeEnum;
124 InitInt(name, defaultVal, 0, static_cast<int>(listItems.size()) - 1,
"", flags | kFlagStepped, group);
127 for (
auto& item : listItems)
129 SetDisplayText(idx++, item);
133 void IParam::InitInt(
const char* name,
int defaultVal,
int minVal,
int maxVal,
const char* label,
int flags,
const char* group)
135 if (mType == kTypeNone) mType = kTypeInt;
137 InitDouble(name, (
double) defaultVal, (
double) minVal, (
double) maxVal, 1.0, label, flags | kFlagStepped, group);
140 void IParam::InitDouble(
const char* name,
double defaultVal,
double minVal,
double maxVal,
double step,
const char* label,
int flags,
const char* group,
const Shape& shape,
EParamUnit unit,
DisplayFunc displayFunc)
142 if (mType == kTypeNone) mType = kTypeDouble;
148 strcpy(mLabel, label);
149 strcpy(mParamGroup, group);
153 mMax = std::max(maxVal, minVal + step);
155 mDefault = defaultVal;
158 mDisplayFunction = displayFunc;
162 for (mDisplayPrecision = 0;
163 mDisplayPrecision < MAX_PARAM_DISPLAY_PRECISION && step != floor(step);
164 ++mDisplayPrecision, step *= 10.0)
169 mShape = std::unique_ptr<Shape>(shape.
Clone());
173 void IParam::InitFrequency(
const char *name,
double defaultVal,
double minVal,
double maxVal,
double step,
int flags,
const char *group)
175 InitDouble(name, defaultVal, minVal, maxVal, step,
"Hz", flags, group,
ShapeExp(), kUnitFrequency);
178 void IParam::InitSeconds(
const char *name,
double defaultVal,
double minVal,
double maxVal,
double step,
int flags,
const char *group)
180 InitDouble(name, defaultVal, minVal, maxVal, step,
"Seconds", flags, group,
ShapeLinear(), kUnitSeconds);
185 InitDouble(name, defaultVal, minVal, maxVal, 1,
"ms", flags, group,
ShapeLinear(), kUnitMilliseconds);
188 void IParam::InitPitch(
const char *name,
int defaultVal,
int minVal,
int maxVal,
int flags,
const char *group,
bool middleCisC)
190 InitEnum(name, defaultVal, (maxVal - minVal) + 1,
"", flags, group);
191 WDL_String displayText;
192 for (
auto i = minVal; i <= maxVal; i++)
195 SetDisplayText(i - minVal, displayText.Get());
199 void IParam::InitGain(
const char *name,
double defaultVal,
double minVal,
double maxVal,
double step,
int flags,
const char *group)
201 InitDouble(name, defaultVal, minVal, maxVal, step,
"dB", flags, group,
ShapeLinear(), kUnitDB);
204 void IParam::InitPercentage(
const char *name,
double defaultVal,
double minVal,
double maxVal,
int flags,
const char *group)
206 InitDouble(name, defaultVal, minVal, maxVal, 1,
"%", flags, group,
ShapeLinear(), kUnitPercentage);
211 InitDouble(name, defaultVal, minVal, maxVal, 1,
"degrees", flags, group,
ShapeLinear(), kUnitDegrees);
214 void IParam::Init(
const IParam& p,
const char* searchStr,
const char* replaceStr,
const char* newGroup)
216 if (mType == kTypeNone) mType = p.
Type();
218 WDL_String str(p.mName);
219 WDL_String group(p.mParamGroup);
221 if (CStringHasContents(searchStr))
223 char* pos = strstr(str.Get(), searchStr);
227 int insertionPos =
static_cast<int>(str.Get() - pos);
228 str.DeleteSub(insertionPos, static_cast<int>(strlen(searchStr)));
229 str.Insert(replaceStr, insertionPos);
233 if (CStringHasContents(newGroup))
238 InitDouble(str.Get(), p.mDefault, p.mMin, p.mMax, p.mStep, p.mLabel, p.mFlags, group.Get(), *p.mShape, p.mUnit, p.mDisplayFunction);
244 SetDisplayText(val, str);
250 int n = mDisplayTexts.GetSize();
251 mDisplayTexts.Resize(n + 1);
252 DisplayText* pDT = mDisplayTexts.Get() + n;
254 strcpy(pDT->mText, str);
259 mDisplayPrecision = precision;
264 if (normalized) value = FromNormalized(value);
266 if (mDisplayFunction !=
nullptr)
268 mDisplayFunction(value, str);
274 const char* displayText = GetDisplayText(value);
276 if (CStringHasContents(displayText))
278 str.Set(displayText, MAX_PARAM_DISPLAY_LEN);
283 double displayValue = value;
285 if (mFlags & kFlagNegateDisplay)
286 displayValue = -displayValue;
289 if (!displayValue) displayValue = 0.0;
291 if (mDisplayPrecision == 0)
293 str.SetFormatted(MAX_PARAM_DISPLAY_LEN,
"%d", static_cast<int>(round(displayValue)));
295 else if ((mFlags & kFlagSignDisplay) && displayValue)
298 sprintf(fmt,
"%%+.%df", mDisplayPrecision);
299 str.SetFormatted(MAX_PARAM_DISPLAY_LEN, fmt, displayValue);
303 str.SetFormatted(MAX_PARAM_DISPLAY_LEN,
"%.*f", mDisplayPrecision, displayValue);
314 return (CStringHasContents(GetDisplayText(static_cast<int>(mValue.load())))) ?
"" : mLabel;
324 return mDisplayTexts.GetSize();
329 int n = mDisplayTexts.GetSize();
330 for (DisplayText* pDT = mDisplayTexts.Get(); n; --n, ++pDT)
332 if (value == pDT->mValue)
return pDT->mText;
339 DisplayText* pDT = mDisplayTexts.Get()+idx;
340 if (pValue) *pValue = pDT->mValue;
346 int n = mDisplayTexts.GetSize();
347 for (DisplayText* pDT = mDisplayTexts.Get(); n; --n, ++pDT)
349 if (!strcmp(str, pDT->mText))
351 *pValue = pDT->mValue;
361 bool mapped = (bool) NDisplayTexts();
364 mapped = MapDisplayText(str, &v);
366 if (!mapped && Type() != kTypeEnum && Type() != kTypeBool)
370 if (mFlags & kFlagNegateDisplay)
388 json.AppendFormatted(8192,
"{");
389 json.AppendFormatted(8192,
"\"id\":%i, ", idx);
390 json.AppendFormatted(8192,
"\"name\":\"%s\", ", GetName());
393 case IParam::kTypeNone:
395 case IParam::kTypeBool:
396 json.AppendFormatted(8192,
"\"type\":\"%s\", ",
"bool");
398 case IParam::kTypeInt:
399 json.AppendFormatted(8192,
"\"type\":\"%s\", ",
"int");
401 case IParam::kTypeEnum:
402 json.AppendFormatted(8192,
"\"type\":\"%s\", ",
"enum");
404 case IParam::kTypeDouble:
405 json.AppendFormatted(8192,
"\"type\":\"%s\", ",
"float");
410 json.AppendFormatted(8192,
"\"min\":%f, ", GetMin());
411 json.AppendFormatted(8192,
"\"max\":%f, ", GetMax());
412 json.AppendFormatted(8192,
"\"default\":%f, ", GetDefault());
413 json.AppendFormatted(8192,
"\"rate\":\"control\"");
414 json.AppendFormatted(8192,
"}");
419 DBGMSG(
"%s %f", GetName(), 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.
const char * GetName() const
Returns the parameter's name.
int NDisplayTexts() const
Get the number of display texts for the parameter.
IParam::EDisplayType GetDisplayType() const override
double ValueToNormalized(double value, const IParam ¶m) const override
Returns the normalized value from a real value, based on an IParam'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.
IPlug's parameter class.
const char * GetDisplayText(double value) const
Get the display text for a particular value.
double NormalizedToValue(double value, const IParam ¶m) const override
Returns the real value from a normalized input, based on an IParam's settings.
IPlug's parameter class.
double NormalizedToValue(double value, const IParam ¶m) const override
Returns the real value from a normalized input, based on an IParam's settings.
Exponential parameter shaping.
Base struct for parameter shaping.
IPlug logging a.k.a tracing functionality.
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.
double GetMin() const
Returns the parameter'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.
static void MidiNoteName(double midiPitch, WDL_String ¬eName, bool cents=false, bool middleCisC4=false)
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's maximum value.
std::function< void(double, WDL_String &)> DisplayFunc
DisplayFunc allows custom parameter display functions, defined by a lambda matching this signature...
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.
const char * GetGroup() const
Returns the parameter's group.
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's label.
double ValueToNormalized(double value, const IParam ¶m) const override
Returns the normalized value from a real value, based on an IParam's settings.
void PrintDetails() const
Helper to print the parameter details to debug console in debug builds.
double ValueToNormalized(double value, const IParam ¶m) const override
Returns the normalized value from a real value, based on an IParam's settings.
EParamUnit
Used by AudioUnit plugins to determine the appearance of parameters, based on the kind of data they r...
EParamType Type() const
Get the parameter'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 Init(const IParam ¶m) override
Initializes the shape instance.
void Init(const IParam &p, const char *searchStr="", const char *replaceStr="", const char *newGroup="")
Initialize the parameter based on another parameter, replacing a CString in the name.
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.
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.
double NormalizedToValue(double value, const IParam ¶m) const override
Returns the real value from a normalized input, based on an IParam's settings.
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
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's range in one method call.
void SetDisplayText(double value, const char *str)
Set some text to display for a particular value, e.g.
const char * GetDisplayTextAtIdx(int idx, double *pValue=nullptr) const
Get the display text at a particular index.