Jamba C++ API  4.4.0
ParamDef.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020 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 "ParamConverters.h"
21 #include "ParamSerializers.h"
22 #include "Messaging.h"
23 #include "NormalizedState.h"
24 
25 #include <base/source/fstreamer.h>
26 #include <pluginterfaces/vst/vsttypes.h>
27 #include <pluginterfaces/vst/ivsteditcontroller.h>
28 #include <pluginterfaces/vst/ivstunits.h>
29 
30 #include <string>
31 #include <memory>
32 
33 namespace pongasoft::VST {
34 
35 using namespace Steinberg;
36 using namespace Steinberg::Vst;
37 
38 // forward declaration required for API
39 namespace GUI::Params {
40 class IGUIJmbParameter;
41 }
42 
46 class IParamDef : public std::enable_shared_from_this<IParamDef>
47 {
48 public:
51  enum class Owner
52  {
53  kRT,
54  kGUI
55  };
56 
58  static constexpr int16 kVersionNotDeprecated = -1;
59 
60 public:
61  IParamDef(ParamID const iParamID,
62  VstString16 iTitle,
63  Owner const iOwner,
64  bool const iTransient,
65  int16 const iDeprecatedSince) :
66  fParamID{iParamID},
67  fTitle{std::move(iTitle)},
68  fOwner{iOwner},
69  fTransient{iTransient},
70  fDeprecatedSince{iDeprecatedSince}
71  {}
72 
73  virtual ~IParamDef() = default;
74 
76  bool isDeprecated() const { return fDeprecatedSince > kVersionNotDeprecated; }
77 
78 public:
79  const ParamID fParamID;
81  const Owner fOwner; // who owns the parameter (and which stream will it be saved if non transient)
82  const bool fTransient; // not saved in the stream
83  const int16 fDeprecatedSince; // at which version the parameter got deprecated
84 };
85 
86 
90 class RawVstParamDef : public IParamDef
91 {
92 public:
93  RawVstParamDef(ParamID const iParamID,
94  VstString16 iTitle,
95  VstString16 iUnits,
96  ParamValue const iDefaultNormalizedValue,
97  int32 const iStepCount,
98  int32 const iFlags,
99  UnitID const iUnitID,
100  VstString16 iShortTitle,
101  int32 const iPrecision,
102  Owner const iOwner,
103  bool const iTransient,
104  int16 const iDeprecatedSince) :
105  IParamDef(iParamID, std::move(iTitle), iOwner, iTransient, iDeprecatedSince),
106  fUnits{std::move(iUnits)},
107  fDefaultValue{Utils::clampE(iDefaultNormalizedValue, 0.0, 1.0)},
108  fStepCount{iStepCount},
109  fFlags{iFlags},
110  fUnitID{iUnitID},
111  fShortTitle{std::move(iShortTitle)},
112  fPrecision{iPrecision}
113  {}
114 
115 public:
116  // readFromStream
117  ParamValue readFromStream(IBStreamer &iStreamer) const
118  {
119  ParamValue res = fDefaultValue;
120 
121  ParamValue value;
122  if(IBStreamHelper::readDouble(iStreamer, value) == kResultOk)
123  res = value;
124 
125  return res;
126  }
127 
129  ParamValue readFromState(NormalizedState const &iState) const
130  {
131  ParamValue res = fDefaultValue;
132  iState.getNormalizedValue(fParamID, res);
133  return res;
134  }
135 
137  tresult writeToState(ParamValue iValue, NormalizedState &oState) const
138  {
139  return oState.setNormalizedValue(fParamID, iValue);
140  }
141 
142  // toString
143  virtual void toString(ParamValue iNormalizedValue, String128 iString) const
144  {
145  RawParamConverter::staticToString(iNormalizedValue, iString, fPrecision);
146  }
147 
154  virtual std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const
155  {
156  String128 s;
157  s[0] = 0;
158  RawParamConverter::staticToString(iNormalizedValue, s, iPrecision >= 0 ? iPrecision : fPrecision);
159  return VstUtils::toUT8String(s);
160  }
161 
162 public:
164  const ParamValue fDefaultValue;
165  const int32 fStepCount;
166  const int32 fFlags;
167  const UnitID fUnitID;
169  const int32 fPrecision;
170 };
171 
175 template<typename T>
177 {
178 public:
179  using ParamType = T;
180 
181  VstParamDef(ParamID const iParamID,
182  VstString16 iTitle,
183  VstString16 iUnits,
184  ParamType const iDefaultValue,
185  int32 const iFlags,
186  UnitID const iUnitID,
187  VstString16 iShortTitle,
188  int32 const iPrecision,
189  Owner const iOwner,
190  bool const iTransient,
191  int16 const iDeprecatedSince,
192  std::shared_ptr<IParamConverter<ParamType>> iConverter) :
193  RawVstParamDef(iParamID,
194  std::move(iTitle),
195  std::move(iUnits),
196  iConverter ? iConverter->normalize(iDefaultValue) : 0,
197  iConverter ? iConverter->getStepCount() : 0,
198  iFlags,
199  iUnitID,
200  std::move(iShortTitle),
201  iPrecision,
202  iOwner,
203  iTransient,
204  iDeprecatedSince),
205  fDefaultValue{iDefaultValue},
206  fConverter{std::move(iConverter)}
207  {
208  }
209 
212  {
213  return denormalize(RawVstParamDef::readFromState(iState));
214  }
215 
217  tresult writeToState(ParamType const &iValue, NormalizedState &oState) const
218  {
219  return RawVstParamDef::writeToState(normalize(iValue), oState);
220  }
221 
222  // getDefaultValue
223  ParamType getDefaultValue() const { return fDefaultValue; }
224 
225  // shortcut to normalize
226  inline ParamValue normalize(ParamType const &iValue) const
227  {
228  if(fConverter)
229  return fConverter->normalize(iValue);
230  return 0;
231  }
232 
233  // shortcut to denormalize
234  inline ParamType denormalize(ParamValue iNormalizedValue) const
235  {
236  if(fConverter)
237  return fConverter->denormalize(iNormalizedValue);
238  return fDefaultValue;
239  }
240 
244  void toString(ParamValue iNormalizedValue, String128 iString) const override
245  {
246  if(fConverter)
247  fConverter->toString(fConverter->denormalize(iNormalizedValue), iString, fPrecision);
248  else
249  RawVstParamDef::toString(iNormalizedValue, iString);
250  }
251 
258  std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const override
259  {
260  if(fConverter)
261  {
262  String128 s;
263  s[0] = 0;
264  fConverter->toString(fConverter->denormalize(iNormalizedValue), s, iPrecision >= 0 ? iPrecision : fPrecision);
265  return VstUtils::toUT8String(s);
266  }
267  else
268  return RawVstParamDef::toUTF8String(iNormalizedValue, iPrecision);
269  }
270 
271 public:
273  const std::shared_ptr<IParamConverter<ParamType>> fConverter;
274 };
275 
279 class IJmbParamDef : public IParamDef
280 {
281 public:
282  IJmbParamDef(const ParamID iParamID,
283  VstString16 iTitle,
284  Owner const iOwner,
285  bool const iTransient,
286  int16 const iDeprecatedSince,
287  bool const iShared)
288  : IParamDef(iParamID, std::move(iTitle), iOwner, iTransient, iDeprecatedSince),
289  fShared{iShared}
290  {}
291 
292  ~IJmbParamDef() override = default;
293 
294  // writeDefaultValue
295  virtual void writeDefaultValue(std::ostream &oStreamer) const = 0;
296 
300  virtual std::shared_ptr<GUI::Params::IGUIJmbParameter> newGUIParam() = 0;
301 
305  virtual bool isSerializable() const = 0;
306 
307 public:
308  bool const fShared;
309 };
310 
315 template<typename T>
317 {
318 public:
319  using ParamType = T;
320 
321  JmbParamDef(ParamID const iParamID,
322  VstString16 iTitle,
323  Owner const iOwner,
324  bool const iTransient,
325  int16 const iDeprecatedSince,
326  bool const iShared,
327  ParamType const &iDefaultValue,
328  std::shared_ptr<IParamSerializer<ParamType>> iSerializer) :
329  IJmbParamDef(iParamID, std::move(iTitle), iOwner, iTransient, iDeprecatedSince, iShared),
330  fDefaultValue{iDefaultValue},
331  fSerializer{std::move(iSerializer)}
332  {}
333 
334  // readFromStream
335  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override;
336  ParamType readFromStream(IBStreamer &iStreamer) const;
337 
338  // writeToStream
339  tresult writeToStream(ParamType const &iValue, IBStreamer &oStreamer) const override;
340 
341  // writeToStream
342  void writeToStream(ParamType const &iValue, std::ostream &oStreamer) const override;
343 
344  // writeDefaultValue
345  void writeDefaultValue(std::ostream &oStreamer) const override;
346 
347  // readFromMessage
348  tresult readFromMessage(Message const &iMessage, ParamType &oValue) const;
349 
350  // writeToMessage
351  tresult writeToMessage(ParamType const &iValue, Message &oMessage) const;
352 
359  std::string toUTF8String(ParamType const &iValue, int32 iPrecision) const
360  {
361  if(fSerializer)
362  return fSerializer->toString(iValue, iPrecision);
363  else
364  {
365  if constexpr(Utils::is_operator_write_to_ostream_defined<ParamType>)
366  {
367  std::ostringstream s;
368  if(iPrecision >= 0)
369  {
370  s.precision(iPrecision);
371  s.setf(std::ios::fixed);
372  }
373  s << iValue;
374  return s.str();
375  }
376  }
377  return "";
378  }
379 
383  std::shared_ptr<IDiscreteConverter<T>> getDiscreteConverter() const
384  {
385  // Implementation note: at this moment, only checks if the serializer also implements the API.
386  // But possible to add an additional separate field to set it explicitly if there is a need
387  return std::dynamic_pointer_cast<IDiscreteConverter<T>>(fSerializer);
388  }
389 
390  // computeMessageAttrID
391  std::string computeMessageAttrID() const
392  {
393  return "__param__" + std::to_string(fParamID);
394  }
395 
402  std::shared_ptr<GUI::Params::IGUIJmbParameter> newGUIParam() override;
403 
407  bool isSerializable() const override { return fSerializer != nullptr; }
408 
409 public:
411  const std::shared_ptr<IParamSerializer<ParamType>> fSerializer;
412 };
413 
414 //------------------------------------------------------------------------
415 // JmbParamDef::readFromStream
416 //------------------------------------------------------------------------
417 template<typename T>
418 tresult JmbParamDef<T>::readFromStream(IBStreamer &iStreamer, T &oValue) const
419 {
420  if(fSerializer)
421  {
422  return fSerializer->readFromStream(iStreamer, oValue);
423  }
424  else
425  return kResultFalse;
426 }
427 
428 //------------------------------------------------------------------------
429 // JmbParamDef::readFromStream
430 //------------------------------------------------------------------------
431 template<typename T>
432 T JmbParamDef<T>::readFromStream(IBStreamer &iStreamer) const
433 {
434  T value;
435  if(readFromStream(iStreamer, value) != kResultOk)
436  value = fDefaultValue;
437  return value;
438 }
439 
440 
441 //------------------------------------------------------------------------
442 // JmbParamDef::writeToStream
443 //------------------------------------------------------------------------
444 template<typename T>
445 tresult JmbParamDef<T>::writeToStream(const T &iValue, IBStreamer &oStreamer) const
446 {
447  if(fSerializer)
448  return fSerializer->writeToStream(iValue, oStreamer);
449  else
450  return kResultFalse;
451 }
452 
453 //------------------------------------------------------------------------
454 // JmbParamDef::writeToStream
455 //------------------------------------------------------------------------
456 template<typename T>
457 void JmbParamDef<T>::writeToStream(const ParamType &iValue, std::ostream &oStream) const
458 {
459  if(fSerializer)
460  fSerializer->writeToStream(iValue, oStream);
461  else
462  {
463  if constexpr(Utils::is_operator_write_to_ostream_defined<ParamType>)
464  {
465  oStream << iValue;
466  }
467  }
468 }
469 
470 //------------------------------------------------------------------------
471 // JmbParamDef::writeDefaultValue
472 //------------------------------------------------------------------------
473 template<typename T>
474 void JmbParamDef<T>::writeDefaultValue(std::ostream &oStreamer) const
475 {
476  writeToStream(fDefaultValue, oStreamer);
477 }
478 
479 //------------------------------------------------------------------------
480 // JmbParamDef::readFromMessage
481 //------------------------------------------------------------------------
482 template<typename T>
483 tresult JmbParamDef<T>::readFromMessage(Message const &iMessage, ParamType &oValue) const
484 {
485  if(fSerializer)
486  return iMessage.getSerializableValue(computeMessageAttrID().c_str(), *this, oValue);
487  else
488  return kResultFalse;
489 }
490 
491 //------------------------------------------------------------------------
492 // JmbParamDef::writeToMessage
493 //------------------------------------------------------------------------
494 template<typename T>
495 tresult JmbParamDef<T>::writeToMessage(const ParamType &iValue, Message &oMessage) const
496 {
497  if(fSerializer)
498  return oMessage.setSerializableValue(computeMessageAttrID().c_str(), *this, iValue);
499  else
500  return kResultFalse;
501 }
502 
503 //------------------------------------------------------------------------
504 // VstParam - define shortcut notation
505 //------------------------------------------------------------------------
506 template<typename T>
507 using VstParam = std::shared_ptr<VstParamDef<T>>;
508 using RawVstParam = std::shared_ptr<RawVstParamDef>;
509 
510 //------------------------------------------------------------------------
511 // JmbParam - define shortcut notation
512 //------------------------------------------------------------------------
513 template<typename T>
514 using JmbParam = std::shared_ptr<JmbParamDef<T>>;
515 
516 }
tresult readDouble(IBStreamer &iStreamer, double &oValue)
Definition: ParamSerializers.h:144
const std::shared_ptr< IParamConverter< ParamType > > fConverter
Definition: ParamDef.h:273
ParamType readFromState(NormalizedState const &iState) const
Read the value from the (normalized) state.
Definition: ParamDef.h:211
tresult writeToState(ParamValue iValue, NormalizedState &oState) const
Writes the provided value to the (normalized) state.
Definition: ParamDef.h:137
const ParamType fDefaultValue
Definition: ParamDef.h:410
virtual std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const
Return the value as a utf-8 string.
Definition: ParamDef.h:154
void toString(ParamValue iNormalizedValue, String128 iString) const override
Using fConverter::toString
Definition: ParamDef.h:244
const std::shared_ptr< IParamSerializer< ParamType > > fSerializer
Definition: ParamDef.h:411
tresult writeToStream(ParamType const &iValue, IBStreamer &oStreamer) const override
Definition: ParamDef.h:445
Base class for a raw vst parameter definition.
Definition: ParamDef.h:90
const Owner fOwner
Definition: ParamDef.h:81
Simple wrapper class with better api.
Definition: Messaging.h:42
static T clampE(const U &value, const T &lower, const T &upper)
Same as clamp except it will actually fail/assert in debug mode.
Definition: Misc.h:58
const ParamID fParamID
Definition: ParamDef.h:79
ParamType denormalize(ParamValue iNormalizedValue) const
Definition: ParamDef.h:234
tresult setSerializableValue(IAttributeList::AttrID id, IParamSerializer< T > const &iSerializer, T const &iValue)
Serializes the parameter value as an entry in the message.
Definition: Messaging.h:163
const int32 fFlags
Definition: ParamDef.h:166
std::shared_ptr< RawVstParamDef > RawVstParam
Definition: ParamDef.h:508
tresult setNormalizedValue(ParamID iParamID, ParamValue iValue)
Sets the normalized value for the given param id if it exists.
Definition: NormalizedState.cpp:146
const int16 fDeprecatedSince
Definition: ParamDef.h:83
std::string toUTF8String(T const &iValue, Steinberg::int32 iPrecision)
This generic function will determine (at compilation time) whether T can be written to an ostream and...
Definition: Utils.h:49
std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const override
Return the value as a utf-8 string.
Definition: ParamDef.h:258
ParamValue readFromStream(IBStreamer &iStreamer) const
Definition: ParamDef.h:117
ParamValue readFromState(NormalizedState const &iState) const
Read the value from the (normalized) state.
Definition: ParamDef.h:129
const VstString16 fUnits
Definition: ParamDef.h:163
Used to communicate the state between the UI and the RT and read/write to stream.
Definition: NormalizedState.h:37
const ParamType fDefaultValue
Definition: ParamDef.h:272
T ParamType
Definition: ParamDef.h:179
const int32 fStepCount
Definition: ParamDef.h:165
T ParamType
Definition: ParamDef.h:319
static void staticToString(ParamValue const &iValue, String128 oString, int32 iPrecision)
Definition: ParamConverters.h:94
const ParamValue fDefaultValue
Definition: ParamDef.h:164
const bool fTransient
Definition: ParamDef.h:82
std::basic_string< Steinberg::char16 > VstString16
Strings made of char16 characters are represented by the native C++11 type std::basic_string<Steinber...
Definition: Types.h:43
const VstString16 fTitle
Definition: ParamDef.h:80
IParamDef(ParamID const iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient, int16 const iDeprecatedSince)
Definition: ParamDef.h:61
bool isDeprecated() const
Returns true if the parameter is deprecated (meaning it can only be used to upgrade to latest version...
Definition: ParamDef.h:76
VstParamDef(ParamID const iParamID, VstString16 iTitle, VstString16 iUnits, ParamType const iDefaultValue, int32 const iFlags, UnitID const iUnitID, VstString16 iShortTitle, int32 const iPrecision, Owner const iOwner, bool const iTransient, int16 const iDeprecatedSince, std::shared_ptr< IParamConverter< ParamType >> iConverter)
Definition: ParamDef.h:181
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamDef.h:418
Interface that defines a converter from a type T to an int32 given a number of steps (provided by get...
Definition: ParamSerializers.h:45
const VstString16 fShortTitle
Definition: ParamDef.h:168
tresult getNormalizedValue(ParamID iParamID, ParamValue &oValue) const
Returns the normalized value for the given param id if it exists.
Definition: NormalizedState.cpp:131
bool const fShared
Definition: ParamDef.h:308
A vst parameter is represented by a ParamValue type which is a double in the range [0,...
Definition: ParamSerializers.h:105
std::string computeMessageAttrID() const
Definition: ParamDef.h:391
IJmbParamDef(const ParamID iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient, int16 const iDeprecatedSince, bool const iShared)
Definition: ParamDef.h:282
Base class for all ParamDef.
Definition: ParamDef.h:46
ParamType getDefaultValue() const
Definition: ParamDef.h:223
std::shared_ptr< VstParamDef< T > > VstParam
Definition: ParamDef.h:507
ParamValue normalize(ParamType const &iValue) const
Definition: ParamDef.h:226
virtual void toString(ParamValue iNormalizedValue, String128 iString) const
Definition: ParamDef.h:143
Owner
Who owns the parameter (mostly for state saving purposes)
Definition: ParamDef.h:51
Typed parameter definition.
Definition: ParamDef.h:176
const int32 fPrecision
Definition: ParamDef.h:169
bool isSerializable() const override
Definition: ParamDef.h:407
RawVstParamDef(ParamID const iParamID, VstString16 iTitle, VstString16 iUnits, ParamValue const iDefaultNormalizedValue, int32 const iStepCount, int32 const iFlags, UnitID const iUnitID, VstString16 iShortTitle, int32 const iPrecision, Owner const iOwner, bool const iTransient, int16 const iDeprecatedSince)
Definition: ParamDef.h:93
const UnitID fUnitID
Definition: ParamDef.h:167
std::string toUTF8String(ParamType const &iValue, int32 iPrecision) const
Return the value as a utf-8 string.
Definition: ParamDef.h:359
Definition: Clock.h:23
Base class for all non vst parameters (need to provide serialization/deserialization)
Definition: ParamDef.h:316
JmbParamDef(ParamID const iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient, int16 const iDeprecatedSince, bool const iShared, ParamType const &iDefaultValue, std::shared_ptr< IParamSerializer< ParamType >> iSerializer)
Definition: ParamDef.h:321
tresult getSerializableValue(IAttributeList::AttrID id, IParamSerializer< T > const &iSerializer, T &oValue) const
Deserializes the parameter value from an entry in the message.
Definition: Messaging.h:182
std::shared_ptr< JmbParamDef< T > > JmbParam
Definition: ParamDef.h:514
std::shared_ptr< IDiscreteConverter< T > > getDiscreteConverter() const
Definition: ParamDef.h:383
Base class for jamba parameters (non templated)
Definition: ParamDef.h:279
constexpr char const * to_string(bool iValue)
Convenient call to convert a boolean into a string.
Definition: StringUtils.h:28
std::string toUT8String(VstString16 const &iString)
Converts a VstString16 to a regular std::string that is properly utf-8 encoded.
Definition: Utils.h:34
A vst parameter is represented by a ParamValue type which is a double in the range [0,...
Definition: ParamConverters.h:53
tresult writeToState(ParamType const &iValue, NormalizedState &oState) const
Writes the provided value to the (normalized) state.
Definition: ParamDef.h:217