Jamba C++ API  4.0.0
ParamDef.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 "ParamConverters.h"
21 #include "ParamSerializers.h"
22 #include "Messaging.h"
23 
24 #include <base/source/fstreamer.h>
25 #include <pluginterfaces/vst/vsttypes.h>
26 #include <pluginterfaces/vst/ivsteditcontroller.h>
27 #include <pluginterfaces/vst/ivstunits.h>
28 
29 #include <string>
30 #include <memory>
31 
32 namespace pongasoft::VST {
33 
34 using namespace Steinberg;
35 using namespace Steinberg::Vst;
36 
37 // forward declaration required for API
38 namespace GUI::Params {
39 class IGUIJmbParameter;
40 }
41 
45 class IParamDef : public std::enable_shared_from_this<IParamDef>
46 {
47 public:
48  enum class Owner
49  {
50  kRT,
51  kGUI
52  };
53 public:
54  IParamDef(ParamID const iParamID,
55  VstString16 iTitle,
56  Owner const iOwner,
57  bool const iTransient) :
58  fParamID{iParamID},
59  fTitle{std::move(iTitle)},
60  fOwner{iOwner},
61  fTransient{iTransient}
62  {}
63 
64  virtual ~IParamDef() = default;
65 
66 public:
67  const ParamID fParamID;
69  const Owner fOwner; // who owns the parameter (and which stream will it be saved if non transient)
70  const bool fTransient; // not saved in the stream
71 };
72 
73 
77 class RawVstParamDef : public IParamDef
78 {
79 public:
80  RawVstParamDef(ParamID const iParamID,
81  VstString16 iTitle,
82  VstString16 iUnits,
83  ParamValue const iDefaultNormalizedValue,
84  int32 const iStepCount,
85  int32 const iFlags,
86  UnitID const iUnitID,
87  VstString16 iShortTitle,
88  int32 const iPrecision,
89  Owner const iOwner,
90  bool const iTransient) :
91  IParamDef(iParamID, std::move(iTitle), iOwner, iTransient),
92  fUnits{std::move(iUnits)},
93  fDefaultValue{Utils::clampE(iDefaultNormalizedValue, 0.0, 1.0)},
94  fStepCount{iStepCount},
95  fFlags{iFlags},
96  fUnitID{iUnitID},
97  fShortTitle{std::move(iShortTitle)},
98  fPrecision{iPrecision}
99  {}
100 
101 public:
102  // readFromStream
103  ParamValue readFromStream(IBStreamer &iStreamer) const
104  {
105  ParamValue res = fDefaultValue;
106 
107  ParamValue value;
108  if(IBStreamHelper::readDouble(iStreamer, value) == kResultOk)
109  res = value;
110 
111  return res;
112  }
113 
114  // toString
115  virtual void toString(ParamValue iNormalizedValue, String128 iString) const
116  {
117  RawParamConverter::staticToString(iNormalizedValue, iString, fPrecision);
118  }
119 
126  virtual std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const
127  {
128  String128 s;
129  s[0] = 0;
130  RawParamConverter::staticToString(iNormalizedValue, s, iPrecision >= 0 ? iPrecision : fPrecision);
131  return VstUtils::toUT8String(s);
132  }
133 
134 public:
136  const ParamValue fDefaultValue;
137  const int32 fStepCount;
138  const int32 fFlags;
139  const UnitID fUnitID;
141  const int32 fPrecision;
142 };
143 
147 template<typename T>
149 {
150 public:
151  using ParamType = T;
152 
153  VstParamDef(ParamID const iParamID,
154  VstString16 iTitle,
155  VstString16 iUnits,
156  ParamType const iDefaultValue,
157  int32 const iFlags,
158  UnitID const iUnitID,
159  VstString16 iShortTitle,
160  int32 const iPrecision,
161  Owner const iOwner,
162  bool const iTransient,
163  std::shared_ptr<IParamConverter<ParamType>> iConverter) :
164  RawVstParamDef(iParamID,
165  std::move(iTitle),
166  std::move(iUnits),
167  iConverter ? iConverter->normalize(iDefaultValue) : 0,
168  iConverter ? iConverter->getStepCount() : 0,
169  iFlags,
170  iUnitID,
171  std::move(iShortTitle),
172  iPrecision,
173  iOwner,
174  iTransient),
175  fDefaultValue{iDefaultValue},
176  fConverter{std::move(iConverter)}
177  {
178  }
179 
180  // getDefaultValue
181  ParamType getDefaultValue() const { return fDefaultValue; }
182 
183  // shortcut to normalize
184  inline ParamValue normalize(ParamType const &iValue) const
185  {
186  if(fConverter)
187  return fConverter->normalize(iValue);
188  return 0;
189  }
190 
191  // shortcut to denormalize
192  inline ParamType denormalize(ParamValue iNormalizedValue) const
193  {
194  if(fConverter)
195  return fConverter->denormalize(iNormalizedValue);
196  return fDefaultValue;
197  }
198 
202  void toString(ParamValue iNormalizedValue, String128 iString) const override
203  {
204  if(fConverter)
205  fConverter->toString(fConverter->denormalize(iNormalizedValue), iString, fPrecision);
206  else
207  RawVstParamDef::toString(iNormalizedValue, iString);
208  }
209 
216  std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const override
217  {
218  if(fConverter)
219  {
220  String128 s;
221  s[0] = 0;
222  fConverter->toString(fConverter->denormalize(iNormalizedValue), s, iPrecision >= 0 ? iPrecision : fPrecision);
223  return VstUtils::toUT8String(s);
224  }
225  else
226  return RawVstParamDef::toUTF8String(iNormalizedValue, iPrecision);
227  }
228 
229 public:
231  const std::shared_ptr<IParamConverter<ParamType>> fConverter;
232 };
233 
237 class IJmbParamDef : public IParamDef
238 {
239 public:
240  IJmbParamDef(const ParamID iParamID,
241  VstString16 iTitle,
242  Owner const iOwner,
243  bool const iTransient,
244  bool const iShared)
245  : IParamDef(iParamID, std::move(iTitle), iOwner, iTransient),
246  fShared{iShared}
247  {}
248 
249  ~IJmbParamDef() override = default;
250 
251  // writeDefaultValue
252  virtual void writeDefaultValue(std::ostream &oStreamer) const = 0;
253 
257  virtual std::shared_ptr<GUI::Params::IGUIJmbParameter> newGUIParam() = 0;
258 
262  virtual bool isSerializable() const = 0;
263 
264 public:
265  bool const fShared;
266 };
267 
272 template<typename T>
274 {
275 public:
276  using ParamType = T;
277 
278  JmbParamDef(ParamID const iParamID,
279  VstString16 iTitle,
280  Owner const iOwner,
281  bool const iTransient,
282  bool const iShared,
283  ParamType const &iDefaultValue,
284  std::shared_ptr<IParamSerializer<ParamType>> iSerializer) :
285  IJmbParamDef(iParamID, std::move(iTitle), iOwner, iTransient, iShared),
286  fDefaultValue{iDefaultValue},
287  fSerializer{std::move(iSerializer)}
288  {}
289 
290  // readFromStream
291  tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override;
292  ParamType readFromStream(IBStreamer &iStreamer) const;
293 
294  // writeToStream
295  tresult writeToStream(ParamType const &iValue, IBStreamer &oStreamer) const override;
296 
297  // writeToStream
298  void writeToStream(ParamType const &iValue, std::ostream &oStreamer) const override;
299 
300  // writeDefaultValue
301  void writeDefaultValue(std::ostream &oStreamer) const override;
302 
303  // readFromMessage
304  tresult readFromMessage(Message const &iMessage, ParamType &oValue) const;
305 
306  // writeToMessage
307  tresult writeToMessage(ParamType const &iValue, Message &oMessage) const;
308 
315  std::string toUTF8String(ParamType const &iValue, int32 iPrecision) const
316  {
317  if(fSerializer)
318  return fSerializer->toString(iValue, iPrecision);
319  else
320  return "";
321  }
322 
326  std::shared_ptr<IDiscreteConverter<T>> getDiscreteConverter() const
327  {
328  // Implementation note: at this moment, only checks if the serializer also implements the API.
329  // But possible to add an additional separate field to set it explicitly if there is a need
330  return std::dynamic_pointer_cast<IDiscreteConverter<T>>(fSerializer);
331  }
332 
333  // computeMessageAttrID
334  std::string computeMessageAttrID() const
335  {
336  return "__param__" + std::to_string(fParamID);
337  }
338 
345  std::shared_ptr<GUI::Params::IGUIJmbParameter> newGUIParam() override;
346 
350  bool isSerializable() const override { return fSerializer != nullptr; }
351 
352 public:
354  const std::shared_ptr<IParamSerializer<ParamType>> fSerializer;
355 };
356 
357 //------------------------------------------------------------------------
358 // JmbParamDef::readFromStream
359 //------------------------------------------------------------------------
360 template<typename T>
361 tresult JmbParamDef<T>::readFromStream(IBStreamer &iStreamer, T &oValue) const
362 {
363  if(fSerializer)
364  {
365  return fSerializer->readFromStream(iStreamer, oValue);
366  }
367  else
368  return kResultFalse;
369 }
370 
371 //------------------------------------------------------------------------
372 // JmbParamDef::readFromStream
373 //------------------------------------------------------------------------
374 template<typename T>
375 T JmbParamDef<T>::readFromStream(IBStreamer &iStreamer) const
376 {
377  T value;
378  if(readFromStream(iStreamer, value) != kResultOk)
379  value = fDefaultValue;
380  return value;
381 }
382 
383 
384 //------------------------------------------------------------------------
385 // JmbParamDef::writeToStream
386 //------------------------------------------------------------------------
387 template<typename T>
388 tresult JmbParamDef<T>::writeToStream(const T &iValue, IBStreamer &oStreamer) const
389 {
390  if(fSerializer)
391  return fSerializer->writeToStream(iValue, oStreamer);
392  else
393  return kResultFalse;
394 }
395 
396 //------------------------------------------------------------------------
397 // JmbParamDef::writeToStream
398 //------------------------------------------------------------------------
399 template<typename T>
400 void JmbParamDef<T>::writeToStream(const ParamType &iValue, std::ostream &oStreamer) const
401 {
402  if(fSerializer)
403  fSerializer->writeToStream(iValue, oStreamer);
404 }
405 
406 //------------------------------------------------------------------------
407 // JmbParamDef::writeDefaultValue
408 //------------------------------------------------------------------------
409 template<typename T>
410 void JmbParamDef<T>::writeDefaultValue(std::ostream &oStreamer) const
411 {
412  writeToStream(fDefaultValue, oStreamer);
413 }
414 
415 //------------------------------------------------------------------------
416 // JmbParamDef::readFromMessage
417 //------------------------------------------------------------------------
418 template<typename T>
419 tresult JmbParamDef<T>::readFromMessage(Message const &iMessage, ParamType &oValue) const
420 {
421  if(fSerializer)
422  return iMessage.getSerializableValue(computeMessageAttrID().c_str(), *this, oValue);
423  else
424  return kResultFalse;
425 }
426 
427 //------------------------------------------------------------------------
428 // JmbParamDef::writeToMessage
429 //------------------------------------------------------------------------
430 template<typename T>
431 tresult JmbParamDef<T>::writeToMessage(const ParamType &iValue, Message &oMessage) const
432 {
433  if(fSerializer)
434  return oMessage.setSerializableValue(computeMessageAttrID().c_str(), *this, iValue);
435  else
436  return kResultFalse;
437 }
438 
439 //------------------------------------------------------------------------
440 // VstParam - define shortcut notation
441 //------------------------------------------------------------------------
442 template<typename T>
443 using VstParam = std::shared_ptr<VstParamDef<T>>;
444 using RawVstParam = std::shared_ptr<RawVstParamDef>;
445 
446 //------------------------------------------------------------------------
447 // JmbParam - define shortcut notation
448 //------------------------------------------------------------------------
449 template<typename T>
450 using JmbParam = std::shared_ptr<JmbParamDef<T>>;
451 
452 }
tresult readDouble(IBStreamer &iStreamer, double &oValue)
Definition: ParamSerializers.h:144
const std::shared_ptr< IParamConverter< ParamType > > fConverter
Definition: ParamDef.h:231
const ParamType fDefaultValue
Definition: ParamDef.h:353
virtual std::string toUTF8String(ParamValue iNormalizedValue, int32 iPrecision) const
Return the value as a utf-8 string.
Definition: ParamDef.h:126
void toString(ParamValue iNormalizedValue, String128 iString) const override
Using fConverter::toString
Definition: ParamDef.h:202
const std::shared_ptr< IParamSerializer< ParamType > > fSerializer
Definition: ParamDef.h:354
tresult writeToStream(ParamType const &iValue, IBStreamer &oStreamer) const override
Definition: ParamDef.h:388
Base class for a raw vst parameter definition.
Definition: ParamDef.h:77
const Owner fOwner
Definition: ParamDef.h:69
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:67
ParamType denormalize(ParamValue iNormalizedValue) const
Definition: ParamDef.h:192
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:138
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)
Definition: ParamDef.h:80
std::shared_ptr< RawVstParamDef > RawVstParam
Definition: ParamDef.h:444
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:216
ParamValue readFromStream(IBStreamer &iStreamer) const
Definition: ParamDef.h:103
const VstString16 fUnits
Definition: ParamDef.h:135
const ParamType fDefaultValue
Definition: ParamDef.h:230
T ParamType
Definition: ParamDef.h:151
const int32 fStepCount
Definition: ParamDef.h:137
T ParamType
Definition: ParamDef.h:276
static void staticToString(ParamValue const &iValue, String128 oString, int32 iPrecision)
Definition: ParamConverters.h:94
const ParamValue fDefaultValue
Definition: ParamDef.h:136
IJmbParamDef(const ParamID iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient, bool const iShared)
Definition: ParamDef.h:240
const bool fTransient
Definition: ParamDef.h:70
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
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, std::shared_ptr< IParamConverter< ParamType >> iConverter)
Definition: ParamDef.h:153
const VstString16 fTitle
Definition: ParamDef.h:68
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition: ParamDef.h:361
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:140
bool const fShared
Definition: ParamDef.h:265
A vst parameter is represented by a ParamValue type which is a double in the range [0,...
Definition: ParamSerializers.h:105
JmbParamDef(ParamID const iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient, bool const iShared, ParamType const &iDefaultValue, std::shared_ptr< IParamSerializer< ParamType >> iSerializer)
Definition: ParamDef.h:278
std::string computeMessageAttrID() const
Definition: ParamDef.h:334
Base class for all ParamDef.
Definition: ParamDef.h:45
ParamType getDefaultValue() const
Definition: ParamDef.h:181
std::shared_ptr< VstParamDef< T > > VstParam
Definition: ParamDef.h:443
ParamValue normalize(ParamType const &iValue) const
Definition: ParamDef.h:184
virtual void toString(ParamValue iNormalizedValue, String128 iString) const
Definition: ParamDef.h:115
Owner
Definition: ParamDef.h:48
Typed parameter definition.
Definition: ParamDef.h:148
const int32 fPrecision
Definition: ParamDef.h:141
IParamDef(ParamID const iParamID, VstString16 iTitle, Owner const iOwner, bool const iTransient)
Definition: ParamDef.h:54
bool isSerializable() const override
Definition: ParamDef.h:350
const UnitID fUnitID
Definition: ParamDef.h:139
std::string toUTF8String(ParamType const &iValue, int32 iPrecision) const
Return the value as a utf-8 string.
Definition: ParamDef.h:315
Definition: Clock.h:23
Base class for all non vst parameters (need to provide serialization/deserialization)
Definition: ParamDef.h:273
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:450
std::shared_ptr< IDiscreteConverter< T > > getDiscreteConverter() const
Definition: ParamDef.h:326
Base class for jamba parameters (non templated)
Definition: ParamDef.h:237
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