Jamba  3.2.0
ParamConverters.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019 pongasoft
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  *
16  * @author Yan Pujante
17  */
18 #ifndef __PONGASOFT_VST_PARAM_CONVERTERS_H__
19 #define __PONGASOFT_VST_PARAM_CONVERTERS_H__
20 
21 #include <pongasoft/Utils/Misc.h>
22 #include <pongasoft/VST/Types.h>
23 
24 #include <pluginterfaces/vst/vsttypes.h>
25 #include <pluginterfaces/vst/ivstparameterchanges.h>
26 #include <pluginterfaces/base/ustring.h>
27 #include <base/source/fstring.h>
28 #include <pluginterfaces/base/ftypes.h>
29 
30 #include <cmath>
31 #include <algorithm>
32 #include <memory>
33 #include <string>
34 #include <array>
35 #include <vector>
36 #include <type_traits>
37 
38 namespace pongasoft {
39 namespace VST {
40 
41 using namespace Steinberg;
42 using namespace Steinberg::Vst;
43 
51 template<typename T>
53 {
54 public:
55  using ParamType = T;
56  virtual int32 getStepCount() const { return 0; }
57  virtual ParamValue normalize(ParamType const &iValue) const = 0;
58  virtual ParamType denormalize(ParamValue iNormalizedValue) const = 0;
59  virtual void toString(ParamType const &iValue, String128 iString, int32 iPrecision) const { }
60  virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
61  {
62  String128 s;
63  toString(iValue, s, iPrecision);
64  return String(s).text8();
65  }
66 };
67 
71 class RawParamConverter : public IParamConverter<ParamValue>
72 {
73 public:
74 
76 
77  inline ParamValue normalize(ParamValue const &iValue) const override
78  {
79  return Utils::clamp(iValue, 0.0, 1.0);
80  }
81 
82  inline ParamValue denormalize(ParamValue iNormalizedValue) const override
83  {
84  return Utils::clamp(iNormalizedValue, 0.0, 1.0);
85  }
86 
87  inline void toString(ParamValue const &iValue, String128 oString, int32 iPrecision) const override
88  {
89  staticToString(iValue, oString, iPrecision);
90  }
91 
92  static inline void staticToString(ParamValue const &iValue, String128 oString, int32 iPrecision)
93  {
94  Steinberg::UString wrapper(oString, str16BufferSize(String128));
95  if(!wrapper.printFloat(iValue, iPrecision))
96  oString[0] = 0;
97  }
98 };
99 
106 {
107 public:
109 
110  explicit BooleanParamConverter(VstString16 iFalseString = STR16("Off"),
111  VstString16 iTrueString = STR16("On")) :
112  fFalseString{std::move(iFalseString)},
113  fTrueString{std::move(iTrueString)}
114  {}
115 
116  inline int32 getStepCount() const override { return 1; }
117 
118  inline ParamValue normalize(bool const &iValue) const override
119  {
120  return iValue ? 1.0 : 0;
121  }
122 
123  inline bool denormalize(ParamValue iNormalizedValue) const override
124  {
125  return toBoolean(iNormalizedValue);
126  }
127 
128  inline void toString(bool const &iValue, String128 oString, int32 /* iPrecision */) const override
129  {
130  Steinberg::UString wrapper(oString, str16BufferSize(String128));
131  if(iValue)
132  wrapper.assign(fTrueString.c_str());
133  else
134  wrapper.assign(fFalseString.c_str());
135  }
136 
140  inline static bool toBoolean(ParamValue iNormalizedValue) { return iNormalizedValue >= 0.5; }
141 
142 protected:
145 };
146 
150 using Percent = double;
151 
156 class PercentParamConverter : public IParamConverter<Percent>
157 {
158 public:
159 
161 
162  inline ParamValue normalize(double const &iValue) const override
163  {
164  return Utils::clamp(iValue, 0.0, 1.0);
165  }
166 
167  inline double denormalize(ParamValue iNormalizedValue) const override
168  {
169  return Utils::clamp(iNormalizedValue, 0.0, 1.0);
170  }
171 
172  inline void toString(ParamType const &iValue, String128 oString, int32 iPrecision) const override
173  {
174  Steinberg::UString wrapper(oString, str16BufferSize (String128));
175  wrapper.printFloat(iValue * 100, iPrecision);
176  wrapper.append(STR16("%"));
177  }
178 };
179 
184 template<typename IntType = int>
185 static inline ParamValue convertDiscreteValueToNormalizedValue(int32 iStepCount, IntType iDiscreteValue)
186 {
187  auto value = Utils::clamp<int32, int32>(iDiscreteValue, 0, iStepCount);
188  if(value == 0)
189  return value;
190  else
191  return value / static_cast<ParamValue>(iStepCount);
192 }
193 
198 template<typename IntType = int>
199 static inline IntType convertNormalizedValueToDiscreteValue(int32 iStepCount, ParamValue iNormalizedValue)
200 {
201  // ParamValue must remain within its bounds
202  auto value = Utils::clamp(iNormalizedValue, 0.0, 1.0);
203  auto discreteValue = std::floor(std::min(static_cast<ParamValue>(iStepCount), value * (iStepCount + 1)));
204  return static_cast<IntType>(discreteValue);
205 }
206 
212 template<int32 StepCount, typename IntType = int>
214 {
215 public:
216  using ParamType = IntType;
217 
219 
220  // Constructor - you can provide an offset for the toString conversion (ex: counting from 1 instead of 0)
221  explicit DiscreteValueParamConverter(IntType iToStringOffset = 0) : fToStringOffset{iToStringOffset} {}
222 
223  // Constructor with printf style format where the parameter (%d) will be (value + offset)
224  explicit DiscreteValueParamConverter(VstString16 iFormat, IntType iToStringOffset = 0) :
225  fToStringOffset{iToStringOffset}, fFormat{std::move(iFormat)} {}
226 
227  // Constructor with all values defined
228  explicit DiscreteValueParamConverter(std::array<VstString16, StepCount + 1> const &iToStringValues) :
229  fToStringValues(iToStringValues.cbegin(), iToStringValues.cend()) {}
230 
231  inline int32 getStepCount() const override { return StepCount; }
232 
233  inline ParamValue normalize(ParamType const &iDiscreteValue) const override
234  {
235  return convertDiscreteValueToNormalizedValue<IntType>(StepCount, iDiscreteValue);
236  }
237 
238  inline ParamType denormalize(ParamValue iNormalizedValue) const override
239  {
240  return convertNormalizedValueToDiscreteValue<IntType>(StepCount, iNormalizedValue);
241  }
242 
243  // toString
244  void toString(ParamType const &iValue, String128 oString, int32 /* iPrecision */) const override
245  {
246  Steinberg::UString wrapper(oString, str16BufferSize (String128));
247  if(!fFormat.empty())
248  {
249  String s;
250  s.printf(fFormat.c_str(), iValue + fToStringOffset);
251  wrapper.assign(s.text());
252  }
253  else
254  {
255  if(fToStringValues.empty())
256  {
257  if(!wrapper.printInt(iValue + fToStringOffset))
258  oString[0] = 0;
259  }
260  else
261  {
262  wrapper.assign(fToStringValues[iValue].c_str());
263  }
264  }
265  }
266 
267 private:
268  IntType fToStringOffset{};
269  VstString16 fFormat{};
270  std::vector<VstString16> fToStringValues{};
271 };
272 
277 template<typename Enum, Enum MaxValue>
279 {
280 public:
281  using ParamType = Enum;
282 
283  using IntType = std::underlying_type_t<Enum>;
284 
286 
287  // Constructor - you can provide an offset for the toString conversion (ex: counting from 1 instead of 0)
288  explicit EnumParamConverter(IntType iToStringOffset = 0) : fConverter{iToStringOffset} {}
289 
290  // Constructor with printf style format where the parameter (%d) will be (value + offset)
291  explicit EnumParamConverter(VstString16 iFormat, IntType iToStringOffset = 0) : fConverter{std::move(iFormat), iToStringOffset} {}
292 
293  // Constructor with all values defined
294  explicit EnumParamConverter(std::array<VstString16, MaxValue + 1> const &iToStringValues) : fConverter{iToStringValues} {}
295 
296  inline int32 getStepCount() const override { return MaxValue; }
297 
298  inline ParamValue normalize(ParamType const &iDiscreteValue) const override
299  {
300  return fConverter.normalize(static_cast<IntType>(iDiscreteValue));
301  }
302 
303  inline ParamType denormalize(ParamValue iNormalizedValue) const override
304  {
305  return static_cast<Enum>(fConverter.denormalize(iNormalizedValue));
306  }
307 
308  void toString(ParamType const &iValue, String128 oString, int32 iPrecision) const override
309  {
310  fConverter.toString(static_cast<IntType>(iValue), oString, iPrecision);
311  }
312 
313 private:
315 };
316 
317 }
318 }
319 
320 #endif // __PONGASOFT_VST_PARAM_CONVERTERS_H__
Enum ParamType
Definition: ParamConverters.h:281
DiscreteValueParamConverter(VstString16 iFormat, IntType iToStringOffset=0)
Definition: ParamConverters.h:224
static bool toBoolean(ParamValue iNormalizedValue)
Definition: ParamConverters.h:140
static T clamp(const U &iValue, const T &iLower, const T &iUpper)
Definition: Misc.h:33
EnumParamConverter(VstString16 iFormat, IntType iToStringOffset=0)
Definition: ParamConverters.h:291
Definition: Clock.h:22
static ParamValue convertDiscreteValueToNormalizedValue(int32 iStepCount, IntType iDiscreteValue)
Definition: ParamConverters.h:185
virtual void toString(ParamType const &iValue, String128 iString, int32 iPrecision) const
Definition: ParamConverters.h:59
VstString16 fTrueString
Definition: ParamConverters.h:144
ParamValue normalize(ParamType const &iDiscreteValue) const override
Definition: ParamConverters.h:233
std::basic_string< Steinberg::char16 > VstString16
Definition: Types.h:37
VstString16 fFalseString
Definition: ParamConverters.h:143
BooleanParamConverter(VstString16 iFalseString=STR16("Off"), VstString16 iTrueString=STR16("On"))
Definition: ParamConverters.h:110
ParamValue denormalize(ParamValue iNormalizedValue) const override
Definition: ParamConverters.h:82
int32 getStepCount() const override
Definition: ParamConverters.h:116
Definition: ParamConverters.h:71
double Percent
Definition: ParamConverters.h:150
Definition: ParamConverters.h:156
void toString(ParamType const &iValue, String128 oString, int32 iPrecision) const override
Definition: ParamConverters.h:308
DiscreteValueParamConverter< MaxValue, IntType > fConverter
Definition: ParamConverters.h:314
void toString(ParamType const &iValue, String128 oString, int32 iPrecision) const override
Definition: ParamConverters.h:172
Enum ParamType
Definition: ParamConverters.h:55
ParamType denormalize(ParamValue iNormalizedValue) const override
Definition: ParamConverters.h:238
void toString(ParamType const &iValue, String128 oString, int32) const override
Definition: ParamConverters.h:244
ParamValue normalize(double const &iValue) const override
Definition: ParamConverters.h:162
EnumParamConverter(std::array< VstString16, MaxValue+1 > const &iToStringValues)
Definition: ParamConverters.h:294
bool denormalize(ParamValue iNormalizedValue) const override
Definition: ParamConverters.h:123
ParamValue normalize(ParamType const &iDiscreteValue) const override
Definition: ParamConverters.h:298
int32 getStepCount() const override
Definition: ParamConverters.h:231
int32 getStepCount() const override
Definition: ParamConverters.h:296
DiscreteValueParamConverter(IntType iToStringOffset=0)
Definition: ParamConverters.h:221
DiscreteValueParamConverter(std::array< VstString16, StepCount+1 > const &iToStringValues)
Definition: ParamConverters.h:228
Definition: ParamConverters.h:105
Definition: ParamConverters.h:213
ParamValue normalize(bool const &iValue) const override
Definition: ParamConverters.h:118
virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
Definition: ParamConverters.h:60
ParamType denormalize(ParamValue iNormalizedValue) const override
Definition: ParamConverters.h:303
EnumParamConverter(IntType iToStringOffset=0)
Definition: ParamConverters.h:288
static void staticToString(ParamValue const &iValue, String128 oString, int32 iPrecision)
Definition: ParamConverters.h:92
ParamValue normalize(ParamValue const &iValue) const override
Definition: ParamConverters.h:77
void toString(ParamValue const &iValue, String128 oString, int32 iPrecision) const override
Definition: ParamConverters.h:87
double denormalize(ParamValue iNormalizedValue) const override
Definition: ParamConverters.h:167
void toString(bool const &iValue, String128 oString, int32) const override
Definition: ParamConverters.h:128
virtual int32 getStepCount() const
Definition: ParamConverters.h:56
static IntType convertNormalizedValueToDiscreteValue(int32 iStepCount, ParamValue iNormalizedValue)
Definition: ParamConverters.h:199
std::underlying_type_t< Enum > IntType
Definition: ParamConverters.h:283
Definition: ParamConverters.h:278
Definition: ParamConverters.h:52