Jamba C++ API  4.3.0
ParamSerializers.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 #pragma once
19 
20 #include <pongasoft/logging/logging.h>
22 #include <pongasoft/Utils/Misc.h>
24 #include <pluginterfaces/vst/vsttypes.h>
25 #include <base/source/fstreamer.h>
26 #include <string>
27 #include <iostream>
28 #include <memory>
29 #include <sstream>
30 #include <map>
31 #include <vector>
32 
33 namespace pongasoft::VST {
34 
35 using namespace Steinberg;
36 using namespace Steinberg::Vst;
37 
44 template<typename T>
46 {
47 public:
48  virtual int32 getStepCount() const = 0;
49  virtual tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const = 0;
50  virtual tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const = 0;
51 };
52 
62 template<typename T>
64 {
65 public:
66  // Constructor
67  explicit StaticCastDiscreteConverter(int32 iStepCount) : fStepCount(iStepCount)
68  {
69  DCHECK_F(fStepCount > 0);
70  }
71 
72  // getStepCount
73  int32 getStepCount() const override { return fStepCount; }
74 
75  // convertFromDiscreteValue
76  tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const override
77  {
78  iDiscreteValue = Utils::clamp(iDiscreteValue, Utils::ZERO_INT32, fStepCount);
79  oValue = static_cast<T>(iDiscreteValue);
80  return kResultOk;
81  }
82 
83  // convertToDiscreteValue
84  tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const override
85  {
86  oDiscreteValue = static_cast<int32>(iValue);
87  oDiscreteValue = Utils::clamp(oDiscreteValue, Utils::ZERO_INT32, fStepCount);
88  return kResultOk;
89  }
90 
91 protected:
92  int32 fStepCount;
93 };
94 
95 
104 template<typename T>
106 {
107 public:
108  using ParamType = T;
109  virtual tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const = 0;
110  virtual tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const = 0;
111 
117  virtual void writeToStream(ParamType const &iValue, std::ostream &oStream) const
118  {
119  if constexpr(Utils::is_operator_write_to_ostream_defined<ParamType>)
120  {
121  oStream << iValue;
122  }
123  }
124 
125  virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
126  {
127  std::ostringstream s;
128  if(iPrecision >= 0)
129  {
130  s.precision(iPrecision);
131  s.setf(std::ios::fixed);
132  }
133  writeToStream(iValue, s);
134  return s.str();
135  }
136 };
137 
141 namespace IBStreamHelper {
142 
143 // readDouble - contrary to IBStreamer.readDouble, this method does NOT modify oValue if cannot be read
144 inline tresult readDouble(IBStreamer &iStreamer, double &oValue)
145 {
146  double value;
147  if(!iStreamer.readDouble(value))
148  return kResultFalse;
149  oValue = value;
150  return kResultOk;
151 }
152 
153 // readFloat - contrary to IBStreamer.readFloat, this method does NOT modify oValue if cannot be read
154 inline tresult readFloat(IBStreamer &iStreamer, float &oValue)
155 {
156  float value;
157  if(!iStreamer.readFloat(value))
158  return kResultFalse;
159  oValue = value;
160  return kResultOk;
161 }
162 
163 // readFloatArray - contrary to IBStreamer.readFloatArray, this method returns tresult and can use any Int type
164 template<typename Int>
165 inline tresult readFloatArray(IBStreamer &iStreamer, float *oValue, Int iCount)
166 {
167  for(Int i = 0; i < iCount; i++)
168  {
169  if(!iStreamer.readFloat(oValue[i]))
170  return kResultFalse;
171  }
172  return kResultOk;
173 }
174 
175 
176 // readInt64 - contrary to IBStreamer.readInt64, this method does NOT modify oValue if cannot be read
177 inline tresult readInt64(IBStreamer &iStreamer, int64 &oValue)
178 {
179  int64 value;
180  if(!iStreamer.readInt64(value))
181  return kResultFalse;
182  oValue = value;
183  return kResultOk;
184 }
185 
186 // readInt64 - contrary to IBStreamer.readInt64, this method does NOT modify oValue if cannot be read
187 inline tresult readInt64u(IBStreamer &iStreamer, uint64 &oValue)
188 {
189  uint64 value;
190  if(!iStreamer.readInt64u(value))
191  return kResultFalse;
192  oValue = value;
193  return kResultOk;
194 }
195 
196 // readInt32 - contrary to IBStreamer.readInt32, this method does NOT modify oValue if cannot be read
197 inline tresult readInt32(IBStreamer &iStreamer, int32 &oValue)
198 {
199  int32 value;
200  if(!iStreamer.readInt32(value))
201  return kResultFalse;
202  oValue = value;
203  return kResultOk;
204 }
205 
206 // readBool - contrary to IBStreamer.readBool, this method does NOT modify oValue if cannot be read
207 inline tresult readBool(IBStreamer &iStreamer, bool &oValue)
208 {
209  bool value;
210  if(!iStreamer.readBool(value))
211  return kResultFalse;
212  oValue = value;
213  return kResultOk;
214 }
215 
216 }
217 
221 class RawParamSerializer : public IParamSerializer<ParamValue>
222 {
223 public:
224  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
225  {
226  return IBStreamHelper::readDouble(iStreamer, oValue);
227  }
228 
229  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
230  {
231  oStreamer.writeDouble(iValue);
232  return kResultOk;
233  }
234 };
235 
240 {
241 public:
242  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
243  {
244  return IBStreamHelper::readDouble(iStreamer, oValue);
245  }
246 
247  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
248  {
249  oStreamer.writeDouble(iValue);
250  return kResultOk;
251  }
252 };
253 
258 {
259 public:
260  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
261  {
262  return IBStreamHelper::readInt32(iStreamer, oValue);
263  }
264 
265  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
266  {
267  oStreamer.writeInt32(iValue);
268  return kResultOk;
269  }
270 };
271 
276 {
277 public:
278  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
279  {
280  return IBStreamHelper::readInt64(iStreamer, oValue);
281  }
282 
283  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
284  {
285  oStreamer.writeInt64(iValue);
286  return kResultOk;
287  }
288 };
289 
294 {
295 public:
296  explicit BooleanParamSerializer(std::string iFalseString = "Off",
297  std::string iTrueString = "On") :
298  fFalseString{std::move(iFalseString)},
299  fTrueString{std::move(iTrueString)}
300  {}
301 
302  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
303  {
304  return IBStreamHelper::readBool(iStreamer, oValue);
305  }
306 
307  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
308  {
309  oStreamer.writeBool(iValue);
310  return kResultOk;
311  }
312 
313  void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
314  {
315  oStream << (iValue ? fTrueString : fFalseString);
316  }
317 
318 private:
319  inline int32 getStepCount() const override { return 1; }
320 
321  tresult convertFromDiscreteValue(int32 iDiscreteValue, bool &oValue) const override
322  {
323  oValue = iDiscreteValue != 0;
324  return kResultOk;
325  }
326 
327  tresult convertToDiscreteValue(const bool &iValue, int32 &oDiscreteValue) const override
328  {
329  oDiscreteValue = iValue ? 1 : 0;
330  return kResultOk;
331  }
332 
333 protected:
334  std::string fFalseString;
335  std::string fTrueString;
336 };
337 
338 
344 template<int size = 128>
345 class CStringParamSerializer : public IParamSerializer<char[size]>
346 {
347 public:
348  using ParamType = char[size];
349 
350  // readFromStream
351  inline tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
352  {
353  if(iStreamer.readRaw(static_cast<void*>(oValue), size) == size)
354  {
355  oValue[size - 1] = 0; // making sure it is null terminated
356  return kResultOk;
357  }
358  else
359  return kResultFalse;
360  }
361 
362  // writeToStream - IBStreamer
363  inline tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
364  {
365  if(oStreamer.writeRaw(static_cast<void const *>(iValue), size) == size)
366  return kResultOk;
367  else
368  return kResultFalse;
369  }
370 
371  // writeToStream - std::ostream
372  void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
373  {
374  if(std::find(std::begin(iValue), std::end(iValue), 0) != std::end(iValue))
375  {
376  // this means that the string is null terminated... we are good
377  oStream << iValue;
378  }
379  else
380  {
381  char8 str[size];
382  std::copy(std::begin(iValue), std::end(iValue), std::begin(str));
383  str[size - 1] = 0; // make the copy null terminated
384  oStream << str;
385  DLOG_F(WARNING, "%s not properly null terminated!", str);
386  }
387  }
388 };
389 
417 template<typename T, class Compare = std::less<T>>
419 {
420 public:
423  using TMap = std::map<T, std::pair<std::string, int32>, Compare>;
424 
427  using TList = std::vector<T>;
428 
431  using ConstructorType = std::initializer_list<std::pair<const T, std::string>> const &;
432 
433  using ParamType = T;
434 
435  // DiscreteTypeParamSerializer
437  {
438 #ifndef NDEBUG
439  // by definition, a discrete parameter has a step count > 0
440  auto stepCount = static_cast<int32>(iInitList.size() - 1);
441  DCHECK_F(stepCount > 0);
442 #endif
443 
444  int32 i = 0;
445  for(auto &pair : iInitList)
446  {
447  fMap[pair.first] = std::make_pair(pair.second, i);
448  fList.emplace_back(pair.first);
449  i++;
450  }
451 
452  // sanity check... if not the same size it means that 2 entries in the list were the same!
453  DCHECK_F(fList.size() == fMap.size());
454  }
455 
456  // getStepCount
457  inline int32 getStepCount() const override { return static_cast<int32>(fMap.size() - 1); }
458 
459  // convertFromDiscreteValue
460  tresult convertFromDiscreteValue(int32 iDiscreteValue, ParamType &oValue) const override
461  {
462  if(iDiscreteValue < 0 || iDiscreteValue > getStepCount())
463  return kResultFalse;
464  oValue = fList[iDiscreteValue];
465  return kResultOk;
466  }
467 
468  // convertToDiscreteValue
469  tresult convertToDiscreteValue(ParamType const &iValue, int32 &oDiscreteValue) const override
470  {
471  auto iter = fMap.find(iValue);
472  if(iter != fMap.cend())
473  {
474  oDiscreteValue = std::get<1>(iter->second);
475  return kResultOk;
476  }
477  else
478  {
479  DLOG_F(WARNING, "could not convertToDiscreteValue...");
480  return kResultFalse;
481  }
482  }
483 
484  // readFromStream
485  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
486  {
487  int32 discreteValue;
488  if(IBStreamHelper::readInt32(iStreamer, discreteValue) == kResultOk)
489  {
490  return convertFromDiscreteValue(discreteValue, oValue);
491  }
492  return kResultFalse;
493  }
494 
495  // writeToStream
496  tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
497  {
498  int32 discreteValue;
499  if(convertToDiscreteValue(iValue, discreteValue) == kResultOk)
500  {
501  if(oStreamer.writeInt32(discreteValue))
502  return kResultOk;
503  }
504 
505  return kResultFalse;
506  }
507 
508  // writeToStream
509  void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
510  {
511  auto iter = fMap.find(iValue);
512  if(iter != fMap.cend())
513  {
514  oStream << std::get<0>(iter->second);
515  }
516  }
517 
518 private:
519  TMap fMap{};
520  TList fList{};
521 };
522 
523 }
This parameter handles serializing a double parameter.
Definition: ParamSerializers.h:239
tresult readDouble(IBStreamer &iStreamer, double &oValue)
Definition: ParamSerializers.h:144
tresult readFloat(IBStreamer &iStreamer, float &oValue)
Definition: ParamSerializers.h:154
static T clamp(const U &iValue, const T &iLower, const T &iUpper)
Make sure that the value remains within its bounds.
Definition: Misc.h:33
This parameter handles serializing a int64 parameter.
Definition: ParamSerializers.h:275
tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const override
Definition: ParamSerializers.h:84
tresult readInt64u(IBStreamer &iStreamer, uint64 &oValue)
Definition: ParamSerializers.h:187
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:363
char[size] ParamType
Definition: ParamSerializers.h:348
std::initializer_list< std::pair< const T, std::string > > const & ConstructorType
Defines the type for the constructor argument.
Definition: ParamSerializers.h:431
This parameter handles serializing a bool parameter.
Definition: ParamSerializers.h:293
constexpr auto ZERO_INT32
Definition: Constants.h:24
This parameter handles serializing a raw parameter (ParamValue)
Definition: ParamSerializers.h:221
int32 getStepCount() const override
Definition: ParamSerializers.h:457
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:247
tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const override
Definition: ParamSerializers.h:76
tresult convertFromDiscreteValue(int32 iDiscreteValue, bool &oValue) const override
Definition: ParamSerializers.h:321
std::vector< T > TList
Defines the mapping: discrete value [0, stepCount] to T.
Definition: ParamSerializers.h:427
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:260
tresult readInt32(IBStreamer &iStreamer, int32 &oValue)
Definition: ParamSerializers.h:197
DiscreteTypeParamSerializer(ConstructorType iInitList)
Definition: ParamSerializers.h:436
tresult convertToDiscreteValue(ParamType const &iValue, int32 &oDiscreteValue) const override
Definition: ParamSerializers.h:469
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:265
tresult readFloatArray(IBStreamer &iStreamer, float *oValue, Int iCount)
Definition: ParamSerializers.h:165
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:302
tresult convertFromDiscreteValue(int32 iDiscreteValue, ParamType &oValue) const override
Definition: ParamSerializers.h:460
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:283
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:351
int32 fStepCount
Definition: ParamSerializers.h:92
A parameter backed by a C type string (char[size]).
Definition: ParamSerializers.h:345
void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
By default, this implementation simply writes the value to the stream IF it is possible (determined a...
Definition: ParamSerializers.h:313
tresult readBool(IBStreamer &iStreamer, bool &oValue)
Definition: ParamSerializers.h:207
std::map< T, std::pair< std::string, int32 >, Compare > TMap
Maintains the map of possible values of T (defined in constructor)
Definition: ParamSerializers.h:423
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:229
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:307
Interface that defines a converter from a type T to an int32 given a number of steps (provided by get...
Definition: ParamSerializers.h:45
std::string fFalseString
Definition: ParamSerializers.h:334
BooleanParamSerializer(std::string iFalseString="Off", std::string iTrueString="On")
Definition: ParamSerializers.h:296
void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
Definition: ParamSerializers.h:372
A vst parameter is represented by a ParamValue type which is a double in the range [0,...
Definition: ParamSerializers.h:105
This parameter handles serializing a int32 parameter.
Definition: ParamSerializers.h:257
virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
Definition: ParamSerializers.h:125
tresult convertToDiscreteValue(const bool &iValue, int32 &oDiscreteValue) const override
Definition: ParamSerializers.h:327
This converters maps a list of values of type T to discrete values.
Definition: ParamSerializers.h:418
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:224
virtual void writeToStream(ParamType const &iValue, std::ostream &oStream) const
By default, this implementation simply writes the value to the stream IF it is possible (determined a...
Definition: ParamSerializers.h:117
int32 getStepCount() const override
Definition: ParamSerializers.h:319
tresult readInt64(IBStreamer &iStreamer, int64 &oValue)
Definition: ParamSerializers.h:177
Definition: Clock.h:23
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:278
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:242
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition: ParamSerializers.h:496
int32 getStepCount() const override
Definition: ParamSerializers.h:73
void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
By default, this implementation simply writes the value to the stream IF it is possible (determined a...
Definition: ParamSerializers.h:509
ParamValue ParamType
Definition: ParamSerializers.h:108
This implementation simply cast T to an int32 (and vice-versa).
Definition: ParamSerializers.h:63
StaticCastDiscreteConverter(int32 iStepCount)
Definition: ParamSerializers.h:67
std::string fTrueString
Definition: ParamSerializers.h:335
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamSerializers.h:485