AAX SDK  2.4.1
Avid Audio Extensions Development Kit
AAX_CRangeTaperDelegate.h
Go to the documentation of this file.
1 /*================================================================================================*/
2 /*
3  *
4  * Copyright 2013-2017, 2019 by Avid Technology, Inc.
5  * All rights reserved.
6  *
7  * CONFIDENTIAL: This document contains confidential information. Do not
8  * read or examine this document unless you are an Avid Technology employee
9  * or have signed a non-disclosure agreement with Avid Technology which protects
10  * the confidentiality of this document. DO NOT DISCLOSE ANY INFORMATION
11  * CONTAINED IN THIS DOCUMENT TO ANY THIRD-PARTY WITHOUT THE PRIOR WRITTEN CONSENT
12  * OF Avid Technology, INC.
13  *
14  */
15 
22 /*================================================================================================*/
23 
24 
25 #ifndef AAX_CRANGETAPERDELEGATE_H
26 #define AAX_CRANGETAPERDELEGATE_H
27 
28 #include "AAX_ITaperDelegate.h"
29 #include "AAX.h" //for types
30 
31 #include <cmath> //for floor()
32 #include <vector>
33 
34 
82 template <typename T, int32_t RealPrecision=1000>
84 {
85 public:
99  AAX_CRangeTaperDelegate(T* range, double* rangesSteps, long numRanges, bool useSmartRounding = true);
102 
103  //Virtual Overrides
105  T GetMinimumValue() const AAX_OVERRIDE { return mMinValue; }
106  T GetMaximumValue() const AAX_OVERRIDE { return mMaxValue; }
107  T ConstrainRealValue(T value) const AAX_OVERRIDE;
108  T NormalizedToReal(double normalizedValue) const AAX_OVERRIDE;
109  double RealToNormalized(T realValue) const AAX_OVERRIDE;
110 
111 protected:
112  T Round(double iValue) const;
113  T SmartRound(double value) const;
114 
115 private:
116  T mMinValue;
117  T mMaxValue;
118  long mNumRanges;
119  std::vector<T> mRanges;
120  std::vector<double> mRangesSteps;
121  std::vector<double> mRangesPercents;
122  std::vector<double> mRangesStepsCount;
123  bool mUseSmartRounding;
124 };
125 
126 template <typename T, int32_t RealPrecision>
127 AAX_CRangeTaperDelegate<T, RealPrecision>::AAX_CRangeTaperDelegate(T* ranges, double* rangesSteps, long numRanges, bool useSmartRounding) :
128  AAX_ITaperDelegate<T>(),
129  mMinValue(*ranges),
130  mMaxValue(*(ranges + numRanges)),
131  mNumRanges(numRanges),
132  mRanges( ranges, ranges + numRanges + 1),
133  mRangesSteps( rangesSteps, rangesSteps + numRanges),
134  mUseSmartRounding( useSmartRounding )
135 {
136  mRangesStepsCount.reserve(numRanges);
137  mRangesPercents.reserve(numRanges);
138  int i = 0;
139  for (; i < mNumRanges; i++)
140  {
141  mRangesStepsCount.push_back( (mRanges.at(i + 1) - mRanges.at(i)) / mRangesSteps.at(i));
142  }
143  double numSteps = 0;
144  for (i = 0; i < mNumRanges; i++)
145  {
146  numSteps += mRangesStepsCount.at(i);
147  }
148  for (i = 0; i < mNumRanges; i++)
149  {
150  mRangesPercents.push_back( mRangesStepsCount.at(i) / numSteps );
151  }
152 }
153 
154 template <typename T, int32_t RealPrecision>
156  mMinValue(rhs.mMinValue),
157  mMaxValue(rhs.mMaxValue),
158  mNumRanges(rhs.mNumRanges),
159  mRanges( rhs.mRanges.begin(), rhs.mRanges.end()),
160  mRangesSteps( rhs.mRangesSteps.begin(), rhs.mRangesSteps.end()),
161  mRangesPercents( rhs.mRangesPercents.begin(), rhs.mRangesPercents.end()),
162  mRangesStepsCount( rhs.mRangesStepsCount.begin(), rhs.mRangesStepsCount.end()),
163  mUseSmartRounding( rhs.mUseSmartRounding )
164 {
165 }
166 
167 template <typename T, int32_t RealPrecision>
169 {
170  if (this == &rhs)
171  return *this;
172 
173  this->mMinValue = rhs.mMinValue;
174  this->mMaxValue = rhs.mMaxValue;
175  this->mNumRanges = rhs.mNumRanges;
176  this->mRanges.assign( rhs.mRanges.begin(), rhs.mRanges.end());
177  this->mRangesSteps.assign( rhs.mRangesSteps.begin(), rhs.mRangesSteps.end());
178  this->mRangesPercents.assign( rhs.mRangesPercents.begin(), rhs.mRangesPercents.end());
179  this->mRangesStepsCount.assign( rhs.mRangesStepsCount.begin(), rhs.mRangesStepsCount.end());
180 
181  return *this;
182 }
183 
184 template <typename T, int32_t RealPrecision>
186 {
187  return ((0 >= RealPrecision) ? static_cast<T>(iValue) :
188  (0 <= iValue) ? floor( iValue*RealPrecision + 0.5f ) / RealPrecision :
189  ceil( iValue*RealPrecision - 0.5f ) / RealPrecision
190  );
191 }
192 
193 template <typename T, int32_t RealPrecision>
195 {
197 }
198 
199 template <typename T, int32_t RealPrecision>
201 {
202  if (mMinValue == mMaxValue)
203  return mMinValue;
204 
205  if (RealPrecision)
206  value = Round(value); //reduce the precision to get proper rounding behavior with integers.
207 
208  const T& highValue = mMaxValue > mMinValue ? mMaxValue : mMinValue;
209  const T& lowValue = mMaxValue > mMinValue ? mMinValue : mMaxValue;
210 
211  if (value > highValue)
212  return highValue;
213  if (value < lowValue)
214  return lowValue;
215 
216  return value;
217 }
218 
219 template <typename T, int32_t RealPrecision>
221 {
222  double percentTotal = normalizedValue;
223 
224  double percent = 0.0;
225  long i = 0;
226  for (; i < mNumRanges; i++)
227  {
228  if ((percentTotal >= percent) && (percentTotal < (percent + mRangesPercents.at( i ) )))
229  break;
230  percent += mRangesPercents.at( i );
231  }
232 
233  double extValue;
234  if (i == mNumRanges)
235  extValue = mMaxValue; // our control is 100% of maximum
236  else
237  extValue = mRanges.at(i) + ((mRanges.at(i+1) - mRanges.at(i))*(percentTotal - percent)) / (mRangesPercents.at(i));
238 
239  T realValue = T(extValue);
240  if ( mUseSmartRounding )
241  realValue = SmartRound(extValue); //reduce the precision to get proper rounding behavior with integers.
242 
243  return ConstrainRealValue(realValue);
244 }
245 
246 template <typename T, int32_t RealPrecision>
248 {
249  realValue = ConstrainRealValue(realValue);
250 
251  double percentTotal = 0.0;
252  long i = 0;
253  for (; i < mNumRanges; i++)
254  {
255  if ((realValue >= mRanges[i]) && (realValue < mRanges[i+1]))
256  break;
257  percentTotal += mRangesPercents[i];
258  }
259 
260  if (i == mNumRanges)
261  percentTotal = 1.0; // our control is 100% of maximum
262  else if (mRanges.at(i + 1) == mRanges.at(i))
263  ; // no action; total percent does not change
264  else
265  percentTotal += (realValue - mRanges.at(i))/(mRanges.at(i + 1) - mRanges.at(i)) * mRangesPercents.at(i);
266 
267  double normalizedValue = percentTotal;
268  return normalizedValue;
269 }
270 
271 template <typename T, int32_t RealPrecision>
273 {
274  int32_t i = 0;
275  for (; i < mNumRanges; i++)
276  {
277  if ((value >= mRanges.at(i)) && (value < mRanges.at(i + 1) ))
278  break;
279  if ( i == mNumRanges - 1 )
280  break;
281  }
282 
283  int32_t longVal = 0;
284  if (value >= 0)
285  longVal = int32_t(floor(value / mRangesSteps.at(i) + 0.5));
286  else
287  longVal = int32_t(ceil(value / mRangesSteps.at(i) - 0.5));
288 
289  return static_cast<double>(longVal) * mRangesSteps.at(i);
290 }
291 
292 
293 #endif AAX_CRANGETAPERDELEGATE_H
Various utility definitions for AAX.
#define AAX_OVERRIDE
override keyword macro
Definition: AAX.h:141
Defines the taper conversion behavior for a parameter.
A piecewise-linear taper conforming to AAX_ITaperDelegate.
Definition: AAX_CRangeTaperDelegate.h:84
AAX_CRangeTaperDelegate(T *range, double *rangesSteps, long numRanges, bool useSmartRounding=true)
Constructs a Range Taper with specified minimum and maximum values.
Definition: AAX_CRangeTaperDelegate.h:127
T GetMaximumValue() const AAX_OVERRIDE
Returns the taper's maximum real value.
Definition: AAX_CRangeTaperDelegate.h:106
double RealToNormalized(T realValue) const AAX_OVERRIDE
Normalizes a real parameter value.
Definition: AAX_CRangeTaperDelegate.h:247
T SmartRound(double value) const
Definition: AAX_CRangeTaperDelegate.h:272
T NormalizedToReal(double normalizedValue) const AAX_OVERRIDE
Converts a normalized value to a real value.
Definition: AAX_CRangeTaperDelegate.h:220
T Round(double iValue) const
Definition: AAX_CRangeTaperDelegate.h:185
AAX_CRangeTaperDelegate< T, RealPrecision > * Clone() const AAX_OVERRIDE
Constructs and returns a copy of the taper delegate.
Definition: AAX_CRangeTaperDelegate.h:194
T GetMinimumValue() const AAX_OVERRIDE
Returns the taper's minimum real value.
Definition: AAX_CRangeTaperDelegate.h:105
AAX_CRangeTaperDelegate & operator=(AAX_CRangeTaperDelegate &rhs)
Definition: AAX_CRangeTaperDelegate.h:168
T ConstrainRealValue(T value) const AAX_OVERRIDE
Applies a contraint to the value and returns the constrained value.
Definition: AAX_CRangeTaperDelegate.h:200
Classes for conversion to and from normalized parameter values.
Definition: AAX_ITaperDelegate.h:89