AAX SDK 2.8.0
Avid Audio Extensions Development Kit
Loading...
Searching...
No Matches
AAX_CRangeTaperDelegate.h
Go to the documentation of this file.
1/*================================================================================================*/
2/*
3 *
4 * Copyright 2013-2017, 2019, 2023-2024 Avid Technology, Inc.
5 * All rights reserved.
6 *
7 * This file is part of the Avid AAX SDK.
8 *
9 * The AAX SDK is subject to commercial or open-source licensing.
10 *
11 * By using the AAX SDK, you agree to the terms of both the Avid AAX SDK License
12 * Agreement and Avid Privacy Policy.
13 *
14 * AAX SDK License: https://developer.avid.com/aax
15 * Privacy Policy: https://www.avid.com/legal/privacy-policy-statement
16 *
17 * Or: You may also use this code under the terms of the GPL v3 (see
18 * www.gnu.org/licenses).
19 *
20 * THE AAX SDK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 * EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 * DISCLAIMED.
23 *
24 */
25
32/*================================================================================================*/
33
34
35#ifndef AAX_CRANGETAPERDELEGATE_H
36#define AAX_CRANGETAPERDELEGATE_H
37
38#include "AAX_ITaperDelegate.h"
39#include "AAX.h" //for types
40
41#include <cmath> //for floor()
42#include <vector>
43
44
92template <typename T, int32_t RealPrecision=1000>
94{
95public:
109 AAX_CRangeTaperDelegate(T* range, double* rangesSteps, unsigned long numRanges, bool useSmartRounding = true);
112
113 //Virtual Overrides
115 T GetMinimumValue() const AAX_OVERRIDE { return mMinValue; }
116 T GetMaximumValue() const AAX_OVERRIDE { return mMaxValue; }
117 T ConstrainRealValue(T value) const AAX_OVERRIDE;
118 T NormalizedToReal(double normalizedValue) const AAX_OVERRIDE;
119 double RealToNormalized(T realValue) const AAX_OVERRIDE;
120
121protected:
122 T Round(double iValue) const;
123 T SmartRound(double value) const;
124
125private:
126 T mMinValue;
127 T mMaxValue;
128 unsigned long mNumRanges;
129 std::vector<T> mRanges;
130 std::vector<double> mRangesSteps;
131 std::vector<double> mRangesPercents;
132 std::vector<double> mRangesStepsCount;
133 bool mUseSmartRounding;
134};
135
136template <typename T, int32_t RealPrecision>
137AAX_CRangeTaperDelegate<T, RealPrecision>::AAX_CRangeTaperDelegate(T* ranges, double* rangesSteps, unsigned long numRanges, bool useSmartRounding) :
139 mMinValue(*ranges),
140 mMaxValue(*(ranges + numRanges)),
141 mNumRanges(numRanges),
142 mRanges( ranges, ranges + numRanges + 1),
143 mRangesSteps( rangesSteps, rangesSteps + numRanges),
144 mUseSmartRounding( useSmartRounding )
145{
146 mRangesStepsCount.reserve(mNumRanges);
147 mRangesPercents.reserve(mNumRanges);
148 unsigned int i = 0;
149 for (; i < mNumRanges; i++)
150 {
151 mRangesStepsCount.push_back( (mRanges.at(i + 1) - mRanges.at(i)) / mRangesSteps.at(i));
152 }
153 double numSteps = 0;
154 for (i = 0; i < mNumRanges; i++)
155 {
156 numSteps += mRangesStepsCount.at(i);
157 }
158 for (i = 0; i < mNumRanges; i++)
159 {
160 mRangesPercents.push_back( mRangesStepsCount.at(i) / numSteps );
161 }
162}
163
164template <typename T, int32_t RealPrecision>
166 mMinValue(rhs.mMinValue),
167 mMaxValue(rhs.mMaxValue),
168 mNumRanges(rhs.mNumRanges),
169 mRanges( rhs.mRanges.begin(), rhs.mRanges.end()),
170 mRangesSteps( rhs.mRangesSteps.begin(), rhs.mRangesSteps.end()),
171 mRangesPercents( rhs.mRangesPercents.begin(), rhs.mRangesPercents.end()),
172 mRangesStepsCount( rhs.mRangesStepsCount.begin(), rhs.mRangesStepsCount.end()),
173 mUseSmartRounding( rhs.mUseSmartRounding )
174{
175}
176
177template <typename T, int32_t RealPrecision>
179{
180 if (this == &rhs)
181 return *this;
182
183 this->mMinValue = rhs.mMinValue;
184 this->mMaxValue = rhs.mMaxValue;
185 this->mNumRanges = rhs.mNumRanges;
186 this->mRanges.assign( rhs.mRanges.begin(), rhs.mRanges.end());
187 this->mRangesSteps.assign( rhs.mRangesSteps.begin(), rhs.mRangesSteps.end());
188 this->mRangesPercents.assign( rhs.mRangesPercents.begin(), rhs.mRangesPercents.end());
189 this->mRangesStepsCount.assign( rhs.mRangesStepsCount.begin(), rhs.mRangesStepsCount.end());
190
191 return *this;
192}
193
194template <typename T, int32_t RealPrecision>
196{
197 return ((0 >= RealPrecision) ? static_cast<T>(iValue) :
198 (0 <= iValue) ? static_cast<T>(floor( iValue*RealPrecision + 0.5f ) / RealPrecision) :
199 static_cast<T>(ceil( iValue*RealPrecision - 0.5f ) / RealPrecision)
200 );
201}
202
203template <typename T, int32_t RealPrecision>
205{
207}
208
209template <typename T, int32_t RealPrecision>
211{
212 if (mMinValue == mMaxValue)
213 return mMinValue;
214
215 if (RealPrecision)
216 value = Round(value); //reduce the precision to get proper rounding behavior with integers.
217
218 const T& highValue = mMaxValue > mMinValue ? mMaxValue : mMinValue;
219 const T& lowValue = mMaxValue > mMinValue ? mMinValue : mMaxValue;
220
221 if (value > highValue)
222 return highValue;
223 if (value < lowValue)
224 return lowValue;
225
226 return value;
227}
228
229template <typename T, int32_t RealPrecision>
231{
232 double percentTotal = normalizedValue;
233
234 double percent = 0.0;
235 unsigned long i = 0;
236 for (; i < mNumRanges; i++)
237 {
238 if ((percentTotal >= percent) && (percentTotal < (percent + mRangesPercents.at( i ) )))
239 break;
240 percent += mRangesPercents.at( i );
241 }
242
243 double extValue;
244 if (i == mNumRanges)
245 extValue = mMaxValue; // our control is 100% of maximum
246 else
247 extValue = mRanges.at(i) + ((mRanges.at(i+1) - mRanges.at(i))*(percentTotal - percent)) / (mRangesPercents.at(i));
248
249 T realValue = T(extValue);
250 if ( mUseSmartRounding )
251 realValue = SmartRound(extValue); //reduce the precision to get proper rounding behavior with integers.
252
253 return ConstrainRealValue(realValue);
254}
255
256template <typename T, int32_t RealPrecision>
258{
259 realValue = ConstrainRealValue(realValue);
260
261 double percentTotal = 0.0;
262 unsigned long i = 0;
263 for (; i < mNumRanges; i++)
264 {
265 if ((realValue >= mRanges[i]) && (realValue < mRanges[i+1]))
266 break;
267 percentTotal += mRangesPercents[i];
268 }
269
270 if (i == mNumRanges)
271 percentTotal = 1.0; // our control is 100% of maximum
272 else if (mRanges.at(i + 1) == mRanges.at(i))
273 ; // no action; total percent does not change
274 else
275 percentTotal += (realValue - mRanges.at(i))/static_cast<double>(mRanges.at(i + 1) - mRanges.at(i)) * mRangesPercents.at(i);
276
277 double normalizedValue = percentTotal;
278 return normalizedValue;
279}
280
281template <typename T, int32_t RealPrecision>
283{
284 unsigned long i = 0;
285 for (; i < mNumRanges; i++)
286 {
287 if ((value >= mRanges.at(i)) && (value < mRanges.at(i + 1) ))
288 break;
289 if ( i == mNumRanges - 1 )
290 break;
291 }
292
293 int32_t longVal = 0;
294 if (value >= 0)
295 longVal = int32_t(floor(value / mRangesSteps.at(i) + 0.5));
296 else
297 longVal = int32_t(ceil(value / mRangesSteps.at(i) - 0.5));
298
299 return static_cast<T>(static_cast<double>(longVal) * mRangesSteps.at(i));
300}
301
302
303#endif
Defines the taper conversion behavior for a parameter.
Various utility definitions for AAX.
#define AAX_OVERRIDE
override keyword macro
Definition: AAX.h:164
A piecewise-linear taper conforming to AAX_ITaperDelegate.
Definition: AAX_CRangeTaperDelegate.h:94
T GetMaximumValue() const AAX_OVERRIDE
Returns the taper's maximum real value.
Definition: AAX_CRangeTaperDelegate.h:116
double RealToNormalized(T realValue) const AAX_OVERRIDE
Normalizes a real parameter value.
Definition: AAX_CRangeTaperDelegate.h:257
T SmartRound(double value) const
Definition: AAX_CRangeTaperDelegate.h:282
T NormalizedToReal(double normalizedValue) const AAX_OVERRIDE
Converts a normalized value to a real value.
Definition: AAX_CRangeTaperDelegate.h:230
T Round(double iValue) const
Definition: AAX_CRangeTaperDelegate.h:195
AAX_CRangeTaperDelegate< T, RealPrecision > * Clone() const AAX_OVERRIDE
Constructs and returns a copy of the taper delegate.
Definition: AAX_CRangeTaperDelegate.h:204
AAX_CRangeTaperDelegate(T *range, double *rangesSteps, unsigned long numRanges, bool useSmartRounding=true)
Constructs a Range Taper with specified minimum and maximum values.
Definition: AAX_CRangeTaperDelegate.h:137
T GetMinimumValue() const AAX_OVERRIDE
Returns the taper's minimum real value.
Definition: AAX_CRangeTaperDelegate.h:115
AAX_CRangeTaperDelegate & operator=(AAX_CRangeTaperDelegate &rhs)
Definition: AAX_CRangeTaperDelegate.h:178
T ConstrainRealValue(T value) const AAX_OVERRIDE
Applies a contraint to the value and returns the constrained value.
Definition: AAX_CRangeTaperDelegate.h:210
Definition: AAX_ITaperDelegate.h:99