Jamba C++ API 8.0.0
Loading...
Searching...
No Matches
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 or the MIT license,
5 * at your option. You may not use this file except in compliance with
6 * one of these licenses. You may obtain copies of the licenses at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 * https://opensource.org/licenses/MIT
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 *
17 * @author Yan Pujante
18 */
19#pragma once
20
21#include <pongasoft/logging/logging.h>
25#include <pluginterfaces/vst/vsttypes.h>
26#include <base/source/fstreamer.h>
27#include <string>
28#include <string_view>
29#include <iostream>
30#include <memory>
31#include <sstream>
32#include <map>
33#include <vector>
34#include <concepts>
35
36namespace pongasoft::VST {
37
38using namespace Steinberg;
39using namespace Steinberg::Vst;
40
47template<typename T>
49{
50public:
51 virtual ~IDiscreteConverter() = default;
52 virtual int32 getStepCount() const = 0;
53 virtual tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const = 0;
54 virtual tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const = 0;
55};
56
66template<typename T>
68{
69public:
70 // Constructor
71 explicit StaticCastDiscreteConverter(int32 iStepCount) : fStepCount(iStepCount)
72 {
73 DCHECK_F(fStepCount > 0);
74 }
75
76 // getStepCount
77 int32 getStepCount() const override { return fStepCount; }
78
79 // convertFromDiscreteValue
80 tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const override
81 {
82 iDiscreteValue = Utils::clamp(iDiscreteValue, Utils::ZERO_INT32, fStepCount);
83 oValue = static_cast<T>(iDiscreteValue);
84 return kResultOk;
85 }
86
87 // convertToDiscreteValue
88 tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const override
89 {
90 oDiscreteValue = static_cast<int32>(iValue);
91 oDiscreteValue = Utils::clamp(oDiscreteValue, Utils::ZERO_INT32, fStepCount);
92 return kResultOk;
93 }
94
95protected:
97};
98
109template<typename T>
111{
112public:
113 using ParamType = T;
114
116 virtual ~IParamSerializer() = default;
117
122 virtual tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const { return kNotImplemented; }
123
128 virtual tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const { return kNotImplemented; }
129
135 virtual void writeToStream(ParamType const &iValue, std::ostream &oStream) const
136 {
138 {
139 oStream << iValue;
140 }
141 }
142
143 virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
144 {
145 std::ostringstream s;
146 if(iPrecision >= 0)
147 {
148 s.precision(iPrecision);
149 s.setf(std::ios::fixed);
150 }
151 writeToStream(iValue, s);
152 return s.str();
153 }
154};
155
156template<typename T, typename ParamType>
157concept IsDerivedFromIParamSerializer = std::derived_from<T, IParamSerializer<ParamType>>;
158
160template<typename T>
161concept IsIParamSerializer = requires
162 { typename T::ParamType; } &&
164
168namespace IBStreamHelper {
169
170// readDouble - contrary to IBStreamer.readDouble, this method does NOT modify oValue if cannot be read
171inline tresult readDouble(IBStreamer &iStreamer, double &oValue)
172{
173 double value;
174 if(!iStreamer.readDouble(value))
175 return kResultFalse;
176 oValue = value;
177 return kResultOk;
178}
179
180// readFloat - contrary to IBStreamer.readFloat, this method does NOT modify oValue if cannot be read
181inline tresult readFloat(IBStreamer &iStreamer, float &oValue)
182{
183 float value;
184 if(!iStreamer.readFloat(value))
185 return kResultFalse;
186 oValue = value;
187 return kResultOk;
188}
189
190// readFloatArray - contrary to IBStreamer.readFloatArray, this method returns tresult and can use any Int type
191template<std::integral Int>
192tresult readFloatArray(IBStreamer &iStreamer, float *oValue, Int iCount)
193{
194 for(Int i = 0; i < iCount; i++)
195 {
196 if(!iStreamer.readFloat(oValue[i]))
197 return kResultFalse;
198 }
199 return kResultOk;
200}
201
202
203// readInt64 - contrary to IBStreamer.readInt64, this method does NOT modify oValue if cannot be read
204inline tresult readInt64(IBStreamer &iStreamer, int64 &oValue)
205{
206 int64 value;
207 if(!iStreamer.readInt64(value))
208 return kResultFalse;
209 oValue = value;
210 return kResultOk;
211}
212
213// readInt64 - contrary to IBStreamer.readInt64, this method does NOT modify oValue if cannot be read
214inline tresult readInt64u(IBStreamer &iStreamer, uint64 &oValue)
215{
216 uint64 value;
217 if(!iStreamer.readInt64u(value))
218 return kResultFalse;
219 oValue = value;
220 return kResultOk;
221}
222
223// readInt32 - contrary to IBStreamer.readInt32, this method does NOT modify oValue if cannot be read
224inline tresult readInt32(IBStreamer &iStreamer, int32 &oValue)
225{
226 int32 value;
227 if(!iStreamer.readInt32(value))
228 return kResultFalse;
229 oValue = value;
230 return kResultOk;
231}
232
233// readBool - contrary to IBStreamer.readBool, this method does NOT modify oValue if cannot be read
234inline tresult readBool(IBStreamer &iStreamer, bool &oValue)
235{
236 bool value;
237 if(!iStreamer.readBool(value))
238 return kResultFalse;
239 oValue = value;
240 return kResultOk;
241}
242
243}
244
248class RawParamSerializer : public IParamSerializer<ParamValue>
249{
250public:
251 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
252 {
253 return IBStreamHelper::readDouble(iStreamer, oValue);
254 }
255
256 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
257 {
258 oStreamer.writeDouble(iValue);
259 return kResultOk;
260 }
261};
262
267{
268public:
269 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
270 {
271 return IBStreamHelper::readDouble(iStreamer, oValue);
272 }
273
274 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
275 {
276 oStreamer.writeDouble(iValue);
277 return kResultOk;
278 }
279};
280
285{
286public:
287 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
288 {
289 return IBStreamHelper::readInt32(iStreamer, oValue);
290 }
291
292 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
293 {
294 oStreamer.writeInt32(iValue);
295 return kResultOk;
296 }
297};
298
303{
304public:
305 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
306 {
307 return IBStreamHelper::readInt64(iStreamer, oValue);
308 }
309
310 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
311 {
312 oStreamer.writeInt64(iValue);
313 return kResultOk;
314 }
315};
316
321{
322public:
323 explicit BooleanParamSerializer(std::string iFalseString = "Off",
324 std::string iTrueString = "On") :
325 fFalseString{std::move(iFalseString)},
326 fTrueString{std::move(iTrueString)}
327 {}
328
329 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
330 {
331 return IBStreamHelper::readBool(iStreamer, oValue);
332 }
333
334 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
335 {
336 oStreamer.writeBool(iValue);
337 return kResultOk;
338 }
339
340 void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
341 {
342 oStream << (iValue ? fTrueString : fFalseString);
343 }
344
345 int32 getStepCount() const override { return 1; }
346
347 tresult convertFromDiscreteValue(int32 iDiscreteValue, bool &oValue) const override
348 {
349 oValue = iDiscreteValue != 0;
350 return kResultOk;
351 }
352
353 tresult convertToDiscreteValue(const bool &iValue, int32 &oDiscreteValue) const override
354 {
355 oDiscreteValue = iValue ? 1 : 0;
356 return kResultOk;
357 }
358
359protected:
360 std::string fFalseString;
361 std::string fTrueString;
362};
363
364
370template<int size = 128>
371class CStringParamSerializer : public IParamSerializer<char[size]>
372{
373public:
374 using ParamType = char[size];
375
376 // readFromStream
377 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
378 {
379 if(iStreamer.readRaw(static_cast<void*>(oValue), size) == size)
380 {
381 oValue[size - 1] = 0; // making sure it is null terminated
382 return kResultOk;
383 }
384 else
385 return kResultFalse;
386 }
387
388 // writeToStream - IBStreamer
389 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
390 {
391 if(oStreamer.writeRaw(static_cast<void const *>(iValue), size) == size)
392 return kResultOk;
393 else
394 return kResultFalse;
395 }
396
397 // writeToStream - std::ostream
398 void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
399 {
400 std::string_view sv(iValue, size);
401 auto pos = sv.find('\0');
402 if(pos != std::string_view::npos)
403 {
404 oStream << sv.substr(0, pos);
405 }
406 else
407 {
408 oStream << sv;
409 DLOG_F(WARNING, "%.*s not properly null terminated!", static_cast<int>(size), iValue);
410 }
411 }
412};
413
441template<typename T, class Compare = std::less<T>>
443{
444public:
447 using TMap = std::map<T, std::pair<std::string, int32>, Compare>;
448
451 using TList = std::vector<T>;
452
455 using ConstructorType = std::initializer_list<std::pair<const T, std::string>> const &;
456
457 using ParamType = T;
458
459 // DiscreteTypeParamSerializer
461 {
462#ifndef NDEBUG
463 // by definition, a discrete parameter has a step count > 0
464 auto stepCount = static_cast<int32>(iInitList.size() - 1);
465 DCHECK_F(stepCount > 0);
466#endif
467
468 int32 i = 0;
469 for(auto &pair : iInitList)
470 {
471 fMap[pair.first] = std::make_pair(pair.second, i);
472 fList.emplace_back(pair.first);
473 i++;
474 }
475
476 // sanity check... if not the same size it means that 2 entries in the list were the same!
477 DCHECK_F(fList.size() == fMap.size());
478 }
479
480 // getStepCount
481 int32 getStepCount() const override { return static_cast<int32>(fMap.size() - 1); }
482
483 // convertFromDiscreteValue
484 tresult convertFromDiscreteValue(int32 iDiscreteValue, ParamType &oValue) const override
485 {
486 if(iDiscreteValue < 0 || iDiscreteValue > getStepCount())
487 return kResultFalse;
488 oValue = fList[iDiscreteValue];
489 return kResultOk;
490 }
491
492 // convertToDiscreteValue
493 tresult convertToDiscreteValue(ParamType const &iValue, int32 &oDiscreteValue) const override
494 {
495 auto iter = fMap.find(iValue);
496 if(iter != fMap.cend())
497 {
498 oDiscreteValue = std::get<1>(iter->second);
499 return kResultOk;
500 }
501 else
502 {
503 DLOG_F(WARNING, "could not convertToDiscreteValue...");
504 return kResultFalse;
505 }
506 }
507
508 // readFromStream
509 tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
510 {
511 int32 discreteValue;
512 if(IBStreamHelper::readInt32(iStreamer, discreteValue) == kResultOk)
513 {
514 return convertFromDiscreteValue(discreteValue, oValue);
515 }
516 return kResultFalse;
517 }
518
519 // writeToStream
520 tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
521 {
522 int32 discreteValue;
523 if(convertToDiscreteValue(iValue, discreteValue) == kResultOk)
524 {
525 if(oStreamer.writeInt32(discreteValue))
526 return kResultOk;
527 }
528
529 return kResultFalse;
530 }
531
532 // writeToStream
533 void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
534 {
535 auto iter = fMap.find(iValue);
536 if(iter != fMap.cend())
537 {
538 oStream << std::get<0>(iter->second);
539 }
540 }
541
542private:
545};
546
547}
void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
Definition ParamSerializers.h:340
int32 getStepCount() const override
Definition ParamSerializers.h:345
std::string fFalseString
Definition ParamSerializers.h:360
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:334
tresult convertFromDiscreteValue(int32 iDiscreteValue, bool &oValue) const override
Definition ParamSerializers.h:347
std::string fTrueString
Definition ParamSerializers.h:361
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:329
BooleanParamSerializer(std::string iFalseString="Off", std::string iTrueString="On")
Definition ParamSerializers.h:323
tresult convertToDiscreteValue(const bool &iValue, int32 &oDiscreteValue) const override
Definition ParamSerializers.h:353
A parameter backed by a C type string (char[size]).
Definition ParamSerializers.h:372
void writeToStream(ParamType const &iValue, std::ostream &oStream) const override
Definition ParamSerializers.h:398
char[size] ParamType
Definition ParamSerializers.h:374
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
Definition ParamSerializers.h:389
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
Definition ParamSerializers.h:377
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:533
int32 getStepCount() const override
Definition ParamSerializers.h:481
tresult convertToDiscreteValue(ParamType const &iValue, int32 &oDiscreteValue) const override
Definition ParamSerializers.h:493
tresult convertFromDiscreteValue(int32 iDiscreteValue, ParamType &oValue) const override
Definition ParamSerializers.h:484
std::map< T, std::pair< std::string, int32 >, Compare > TMap
Maintains the map of possible values of T (defined in constructor).
Definition ParamSerializers.h:447
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:520
std::initializer_list< std::pair< const T, std::string > > const & ConstructorType
Defines the type for the constructor argument.
Definition ParamSerializers.h:455
std::vector< T > TList
Defines the mapping: discrete value [0, stepCount] to T.
Definition ParamSerializers.h:451
T ParamType
Definition ParamSerializers.h:457
TMap fMap
Definition ParamSerializers.h:543
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:509
DiscreteTypeParamSerializer(ConstructorType iInitList)
Definition ParamSerializers.h:460
TList fList
Definition ParamSerializers.h:544
This parameter handles serializing a double parameter.
Definition ParamSerializers.h:267
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:274
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:269
Interface that defines a converter from a type T to an int32 given a number of steps (provided by get...
Definition ParamSerializers.h:49
virtual tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const =0
virtual tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const =0
virtual ~IDiscreteConverter()=default
virtual int32 getStepCount() const =0
A vst parameter is represented by a ParamValue type which is a double in the range [0,...
Definition ParamSerializers.h:111
virtual std::string toString(ParamType const &iValue, int32 iPrecision) const
Definition ParamSerializers.h:143
virtual tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:122
virtual tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:128
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:135
T ParamType
Definition ParamSerializers.h:113
virtual ~IParamSerializer()=default
Destructor (needed for polymorphic base type).
This parameter handles serializing a int32 parameter.
Definition ParamSerializers.h:285
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:292
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:287
This parameter handles serializing a int64 parameter.
Definition ParamSerializers.h:303
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:310
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:305
This parameter handles serializing a raw parameter (ParamValue).
Definition ParamSerializers.h:249
tresult writeToStream(const ParamType &iValue, IBStreamer &oStreamer) const override
This method should write iValue to the stream (aka serialization).
Definition ParamSerializers.h:256
tresult readFromStream(IBStreamer &iStreamer, ParamType &oValue) const override
This method should read from the stream and populate oValue accordingly (aka deserialization).
Definition ParamSerializers.h:251
int32 getStepCount() const override
Definition ParamSerializers.h:77
tresult convertToDiscreteValue(T const &iValue, int32 &oDiscreteValue) const override
Definition ParamSerializers.h:88
int32 fStepCount
Definition ParamSerializers.h:96
tresult convertFromDiscreteValue(int32 iDiscreteValue, T &oValue) const override
Definition ParamSerializers.h:80
StaticCastDiscreteConverter(int32 iStepCount)
Definition ParamSerializers.h:71
Allows to detect whether a type defines ostream << x at compile time.
Definition Metaprogramming.h:103
Definition ParamSerializers.h:157
Defines the concept that matches IParamSerializer.
Definition ParamSerializers.h:161
static constexpr T clamp(const U &iValue, const T &iLower, const T &iUpper)
Make sure that the value remains within its bounds.
Definition Misc.h:34
constexpr auto ZERO_INT32
Definition Constants.h:25
IBStreamHelper - Helper functions.
Definition ParamSerializers.h:168
tresult readDouble(IBStreamer &iStreamer, double &oValue)
Definition ParamSerializers.h:171
tresult readFloat(IBStreamer &iStreamer, float &oValue)
Definition ParamSerializers.h:181
tresult readBool(IBStreamer &iStreamer, bool &oValue)
Definition ParamSerializers.h:234
tresult readInt64u(IBStreamer &iStreamer, uint64 &oValue)
Definition ParamSerializers.h:214
tresult readInt32(IBStreamer &iStreamer, int32 &oValue)
Definition ParamSerializers.h:224
tresult readInt64(IBStreamer &iStreamer, int64 &oValue)
Definition ParamSerializers.h:204
tresult readFloatArray(IBStreamer &iStreamer, float *oValue, Int iCount)
Definition ParamSerializers.h:192
Definition Clock.h:24