HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CL_Lag.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CL_Lag.h ( Clip Library, C++)
7  *
8  * COMMENTS:
9  * Applies a lag filter to input data
10  */
11 
12 
13 #ifndef __CL_Lag__
14 #define __CL_Lag__
15 
16 #include <SYS/SYS_Math.h>
17 #include <SYS/SYS_Types.h>
18 #include <UT/UT_Vector.h>
19 
20 #include <algorithm>
21 
22 class UT_Interrupt;
23 
24 class CL_Lag
25 {
26 public:
27 
28  /// Apply a lag filter
29  /// data and result must both be of length size
30  static void solve(const fpreal *data, fpreal *result, int size,
31  fpreal lag_up, fpreal lag_down, fpreal overshoot_up, fpreal overshoot_down,
32  bool sclamp = false, bool aclamp = false,
33  fpreal sclamp_up = 0.0, fpreal sclamp_down = 0.0,
34  fpreal aclamp_up = 0.0, fpreal aclamp_down = 0.0,
35  bool use_value_method = false);
36 
37  /// Apply a lag filter using the magnitude method
38  /// Must provide lambda functions for getting the data (the p1 value) and
39  /// setting the results (based on the index and resulting p1 and)
40  template <class F, class FR, class FP>
41  static void solveRealtimeMagnitude(const F& get_data, const FR& set_results, int start, int end,
42  bool sclamp, bool aclamp,
43  const FP& get_params,
44  UT_VectorR &v0, UT_VectorR &p0);
45 
46  /// Apply a lag filter to realtime data using using the value or amplitude methods
47  /// Must provide a lambda function for computing the p1 value from the data
48  template <class F, class FP>
49  static bool solveRealtime(const F& get_data, fpreal *result, int start, int end,
50  bool sclamp, bool aclamp,
51  const FP& get_params,
52  fpreal &v0, fpreal &p0,
53  bool use_value_method = false);
54 
55 
56 private:
57  static constexpr fpreal LN_PNT_ONE = -2.3025851;
58  static constexpr fpreal MAX_STEADY_DELTA = 0.001;
59 
60  /// Calculate Lag Vector
61  /// Used when computing lag via magnitude
62  static void
63  calculateLagVector(UT_VectorR &v0, UT_VectorR &v1,
64  UT_VectorR &p0, UT_VectorR &p1,
65  UT_VectorR &a0, UT_VectorR &a1,
66  bool sclamp, bool aclamp,
67  const fpreal &lag_up, const fpreal &over_up,
68  const fpreal &sclamp_up, const fpreal &aclamp_up)
69  {
70  fpreal len;
71 
72  // lag
73  p1 *= lag_up;
74  p1.addScaledVec(1.0 - lag_up, p0);
75 
76  // overshoot
77  v1 = p1;
78  v1 -= p0;
79 
80  v1 *= over_up;
81  v1.addScaledVec(1.0 - over_up, v0);
82 
83  // clamp slope
84  if (sclamp)
85  {
86  len = v1.norm();
87  if (len > sclamp_up)
88  v1 *= (sclamp_up / len);
89  p1 = v1;
90  p1 += p0;
91  }
92 
93  // clamp acc
94  a1 = v1;
95  a1 -= v0;
96 
97  if (aclamp)
98  {
99  len = a1.norm();
100  if (len > aclamp_up)
101  a1 *= (aclamp_up / len);
102 
103  v1 = a1;
104  v1 += v0;
105  }
106 
107  p1 = v1;
108  p1 += p0;
109 
110  p0 = p1;
111  v0 = v1;
112  }
113 
114  /// Calculate lag
115  /// Used when computing lag via value or amplitude methods
116  static fpreal calculateLag(bool use_value_method, fpreal &v0, fpreal &p0, fpreal p1,
117  bool sclamp, bool aclamp,
118  const fpreal &lag_up, const fpreal &lag_down,
119  const fpreal &over_up, const fpreal &over_down,
120  const fpreal &sclamp_up, const fpreal &sclamp_down,
121  const fpreal &aclamp_up, const fpreal &aclamp_down)
122  {
123  fpreal cmp = 0.0;
124  fpreal v1 = 0.0;
125  fpreal a1 = 0.0;
126 
127  // lag
128  if (use_value_method)
129  cmp = p1-p0;
130  else
131  cmp = abs(p1)-abs(p0);
132 
133  if (cmp > 0.0)
134  p1 = (1.0 - lag_up)*p0 + lag_up*p1;
135  else if (cmp < 0.0)
136  p1 = (1.0 - lag_down)*p0 + lag_down*p1;
137 
138  // overshoot
139  v1 = p1 - p0;
140 
141  if (v1 > 0)
142  v1 = (1.0 - over_up)*v0 + over_up*v1;
143  else if (v1 < 0)
144  v1 = (1.0 - over_down)*v0 + over_down*v1;
145 
146  // clamp slope
147  if (sclamp)
148  {
149  if (v1 > 0)
150  {
151  if (v1 > sclamp_up)
152  v1 = sclamp_up;
153  }
154  else if (v1 < 0)
155  {
156  if (v1 < - sclamp_down)
157  v1 = -sclamp_down;
158  }
159 
160  }
161 
162  p1 = v1 + p0;
163 
164  // clamp acc
165  a1 = v1 - v0;
166 
167  if (aclamp)
168  {
169  if (a1 > 0)
170  {
171  if (a1 > aclamp_up)
172  a1 = aclamp_up;
173  }
174  else if (a1 < 0)
175  {
176  if (a1 < -aclamp_down)
177  a1 = -aclamp_down;
178  }
179  }
180 
181  v1 = a1 + v0;
182  p0 = p1;
183  v0 = v1;
184 
185  return p1;
186  }
187 };
188 
189 inline void
191  fpreal lag_up, fpreal lag_down, fpreal overshoot_up, fpreal overshoot_down,
192  bool sclamp, bool aclamp,
193  fpreal sclamp_up, fpreal sclamp_down,
194  fpreal aclamp_up, fpreal aclamp_down,
195  bool use_value_method)
196 {
197  if (size < 2)
198  {
199  if (result != data)
200  std::copy(data, data + size, result);
201  return;
202  }
203 
204  fpreal p = data[0];
205  fpreal p1 = data[1];
206  fpreal v = 0.0;
207 
208  fpreal lag0 = (lag_up > 0.0) ? 1.0 - exp(LN_PNT_ONE / lag_up) : 1.0;
209  fpreal lag1 = (lag_down > 0.0) ? 1.0 - exp(LN_PNT_ONE / lag_down) : 1.0;
210  fpreal over0 = (overshoot_up > 0.0) ? 1.0 - exp(LN_PNT_ONE / overshoot_up) : 1.0;
211  fpreal over1 = (overshoot_down > 0.0) ? 1.0 - exp(LN_PNT_ONE / overshoot_down) : 1.0;
212 
213  for (exint idx = 0; idx < size; ++idx)
214  {
215  p1 = data[idx];
216 
217  p1 = calculateLag(use_value_method, v, p, p1,
218  sclamp, aclamp,
219  lag0, lag1, over0, over1,
220  sclamp_up, sclamp_down, aclamp_up, aclamp_down);
221 
222  result[idx] = p1;
223  }
224 }
225 
226 template <class F, class FP>
227 inline bool
229  bool sclamp, bool aclamp,
230  const FP& get_params,
231  fpreal &v0, fpreal &p0,
232  bool use_value_method)
233 {
234  fpreal delta = 0.0;
235  bool steady = true;
236 
237  fpreal lag_up;
238  fpreal lag_down;
239  fpreal over_up;
240  fpreal over_down;
241  fpreal sclamp_up;
242  fpreal sclamp_down;
243  fpreal aclamp_up;
244  fpreal aclamp_down;
245 
246  for (exint i = start; i <= end; i++)
247  {
248  fpreal p1 = get_data(i);
249 
250  if (!get_params(lag_up, lag_down, over_up, over_down,
251  sclamp_up, sclamp_down, aclamp_up, aclamp_down))
252  {
253  break;
254  }
255 
256  fpreal res = calculateLag(use_value_method, v0, p0, p1, sclamp, aclamp,
257  lag_up, lag_down, over_up, over_down,
258  sclamp_up, sclamp_down, aclamp_up, aclamp_down);
259 
260  delta = SYSabs(p1 - res);
261  if (delta > MAX_STEADY_DELTA)
262  steady = false;
263 
264  result[i] = res;
265  }
266 
267  return steady;
268 }
269 
270 template <class F, class FR, class FP>
271 void
272 CL_Lag::solveRealtimeMagnitude(const F& get_data, const FR& set_results, int start, int end,
273  bool sclamp, bool aclamp,
274  const FP& get_params,
275  UT_VectorR &v0, UT_VectorR &p0)
276 {
277  UT_VectorR v1;
278  UT_VectorR p1;
279  UT_VectorR a0;
280  UT_VectorR a1;
281 
282  v1.init(v0.getNL(), v0.getNH());
283  p1.init(v0.getNL(), v0.getNH());
284  a0.init(v0.getNL(), v0.getNH());
285  a1.init(v0.getNL(), v0.getNH());
286 
287  fpreal lag_up;
288  fpreal over_up;
289  fpreal sclamp_up;
290  fpreal aclamp_up;
291 
292  for (exint i = start; i <= end; i++)
293  {
294  get_data(i, p1);
295 
296  if (!get_params(lag_up, over_up, sclamp_up, aclamp_up))
297  {
298  break;
299  }
300 
301  calculateLagVector(v0, v1, p0, p1, a0, a1,
302  sclamp, aclamp,
303  lag_up, over_up,
304  sclamp_up, aclamp_up);
305 
306  set_results(i, p1);
307  }
308 }
309 
310 #endif
static bool solveRealtime(const F &get_data, fpreal *result, int start, int end, bool sclamp, bool aclamp, const FP &get_params, fpreal &v0, fpreal &p0, bool use_value_method=false)
Definition: CL_Lag.h:228
void init(exint nl, exint nh)
Initialize nl, nh and allocate space.
Definition: UT_Vector.C:107
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
const GLdouble * v
Definition: glcorearb.h:837
GLuint start
Definition: glcorearb.h:475
exint getNH() const
Get the high index.
Definition: UT_Vector.h:82
int64 exint
Definition: SYS_Types.h:125
#define SYSabs(a)
Definition: SYS_Math.h:1540
**But if you need a result
Definition: thread.h:613
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
Definition: ImathFun.h:84
static void solveRealtimeMagnitude(const F &get_data, const FR &set_results, int start, int end, bool sclamp, bool aclamp, const FP &get_params, UT_VectorR &v0, UT_VectorR &p0)
Definition: CL_Lag.h:272
auto get_data(std::basic_string< Char > &s) -> Char *
Definition: format.h:331
T norm(int type=2) const
Definition: UT_Vector.C:278
GLuint GLuint end
Definition: glcorearb.h:475
GLfloat v0
Definition: glcorearb.h:816
GLsizeiptr size
Definition: glcorearb.h:664
fpreal64 fpreal
Definition: SYS_Types.h:277
GLfloat GLfloat v1
Definition: glcorearb.h:817
static void solve(const fpreal *data, fpreal *result, int size, fpreal lag_up, fpreal lag_down, fpreal overshoot_up, fpreal overshoot_down, bool sclamp=false, bool aclamp=false, fpreal sclamp_up=0.0, fpreal sclamp_down=0.0, fpreal aclamp_up=0.0, fpreal aclamp_down=0.0, bool use_value_method=false)
Definition: CL_Lag.h:190
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
Definition: format.h:895
Definition: CL_Lag.h:24
exint getNL() const
Get the low index.
Definition: UT_Vector.h:79