Ardour  9.0-pre0-582-g084a23a80d
m2_encoder.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef _ardour_surfaces_m2encoder_h_
20 #define _ardour_surfaces_m2encoder_h_
21 
22 #include <stdint.h>
23 #include "pbd/signals.h"
24 
25 namespace ArdourSurface {
26 
28 {
29  public:
31  virtual ~M2EncoderInterface () {}
32 
33  /* user API */
34  PBD::Signal<void(int)> changed;
35  virtual float value () const { return 0.f; }
36  virtual float range () const { return 0.f; }
37 
38  /* internal API - called from device thread */
39  virtual bool set_value (unsigned int v) { return false; }
40 };
41 
43 {
44  public:
45  M2Encoder (unsigned int upper = 1000)
47  , _upper (upper /* limit, exclusive. eg [0..15]: 16 */)
48  , _value (0)
49  , _initialized (false)
50  {
51  assert (_upper > 7);
52  _wrapcnt = std::max (3U, upper / 6);
53  }
54 
55  float value () const { return _value / (_upper - 1.f); }
56  float range () const { return (_upper - 1.f); }
57 
58  bool set_value (unsigned int v) {
59  if (!_initialized) {
60  _initialized = true;
61  _value = v;
62  return false;
63  }
64 
65  if (v == _value) {
66  return false;
67  }
68 
69  int delta;
70  if (v < _wrapcnt && _value > _upper - _wrapcnt) {
71  // wrap around max -> min
72  delta = v + _upper - _value;
73  }
74  else if (_value < _wrapcnt && v > _upper - _wrapcnt) {
75  // wrap around min -> max
76  delta = v - _upper - _value;
77  }
78  else {
79  delta = v - _value;
80  }
81 
82  _value = v;
83  changed (delta);
84  return true;
85  }
86 
87  protected:
88  unsigned int _upper;
89  unsigned int _value;
90  unsigned int _wrapcnt;
92 };
93 
94 } /* namespace */
95 #endif /* _ardour_surfaces_m2encoder_h_ */
96 
97 
PBD::Signal< void(int)> changed
Definition: m2_encoder.h:34
virtual float value() const
Definition: m2_encoder.h:35
virtual bool set_value(unsigned int v)
Definition: m2_encoder.h:39
virtual float range() const
Definition: m2_encoder.h:36
M2Encoder(unsigned int upper=1000)
Definition: m2_encoder.h:45
float range() const
Definition: m2_encoder.h:56
float value() const
Definition: m2_encoder.h:55
bool set_value(unsigned int v)
Definition: m2_encoder.h:58
unsigned int _wrapcnt
Definition: m2_encoder.h:90