Ardour  8.7-14-g57a6773833
m2_pad.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_m2pad_h_
20 #define _ardour_surfaces_m2pad_h_
21 
22 #include <stdint.h>
23 #include "pbd/signals.h"
24 
25 namespace ArdourSurface {
26 
28 {
29  public:
31  virtual ~M2PadInterface () {}
32 
33  /* user API */
34  PBD::Signal1<void, float> pressed;
35  PBD::Signal0<void> released;
36  PBD::Signal1<void, float> aftertouch;
37  PBD::Signal2<void, float, bool> event;
38  PBD::Signal1<void, float> changed;
39 
40  virtual uint16_t value () const { return 0; }
41  virtual float pressure () const { return 0.f; }
42  virtual void set_color (uint32_t rgba) {}
43 
44  /* internal API - called from device thread */
45  virtual void set_value (uint16_t v) {}
46 
47  virtual void color (uint8_t& r, uint8_t& g, uint8_t& b) const {
48  r = g = b = 0;
49  }
50 };
51 
52 class M2Pad : public M2PadInterface
53 {
54  public:
55  M2Pad ()
56  : M2PadInterface ()
57  , _pressed (false)
58  , _pressure (0)
59  , _last (0)
60  , _cnt (0)
61  , _rgba (0)
62  {
63  for (int i = 0; i < 4; ++i) {
64  hist[i] = 0;
65  }
66  }
67 
68  uint16_t value () const { return _raw; }
69  float pressure () const { return _pressure; }
70 
71  void set_color (uint32_t rgba) { _rgba = rgba; }
72 
73  void color (uint8_t& r, uint8_t& g, uint8_t& b) const
74  {
75  r = ((_rgba >> 24) & 0xff) >> 1;
76  g = ((_rgba >> 16) & 0xff) >> 1;
77  b = ((_rgba >> 8) & 0xff) >> 1;
78  }
79 
80  void set_value (uint16_t v)
81  {
82  // bleed to neighboring pads...
83  static const uint16_t high = 159;
84  static const float low = 159 / 4095.f;
85  static const float mindelta = 32.f / 4096.f;
86 
87  if (_raw != v) {
88  changed (v / 4095.f);
89  _raw = v;
90  }
91 
92  // some pads never return to "0", and there's
93  // TODO map pressure from a min..max range,
94  // even hard hits rarely exceed 3400 or thereabouts.
95  // -> "pad sensitivity" config or "calibrate pads"
96 
97  hist[_cnt] = v;
98  _cnt = (_cnt + 1) & 3;
99 
100  if (_pressed) {
101  const float p = v / 4095.f;
102  _pressure += .1 * (p - _pressure);
103  if (_pressure < low) {
104  _pressure = 0;
105  _pressed = false;
106  released (); /* EMIT SIGNAL */
107  event (_pressure, true); /* EMIT SIGNAL */
108  } else {
109  if (fabsf (_last - _pressure) > mindelta) {
110  _last = _pressure;
111  aftertouch (_pressure); /* EMIT SIGNAL */
112  event (_pressure, false); /* EMIT SIGNAL */
113  }
114  }
115  } else {
116  bool above_thresh = true;
117  uint16_t max = 0;
118  for (int i = 0; i < 4; ++i) {
119  if (hist[i] < high) {
120  above_thresh = false;
121  break;
122  }
123  max = std::max (max, hist[i]);
124  }
125  if (above_thresh) {
126  _pressed = true;
127  _last = _pressure = max / 4095.f;
128  pressed (_pressure);
129  event (_pressure, true); /* EMIT SIGNAL */
130  }
131  }
132  }
133 
134  protected:
135  bool _pressed;
136  float _pressure;
137  uint16_t _raw;
138  float _last;
139  uint16_t hist[4];
140  unsigned int _cnt;
141  uint32_t _rgba;
142 };
143 
144 } /* namespace */
145 #endif /* _ardour_surfaces_m2pad_h_ */
146 
147 
148 
virtual void color(uint8_t &r, uint8_t &g, uint8_t &b) const
Definition: m2_pad.h:47
PBD::Signal1< void, float > changed
Definition: m2_pad.h:38
PBD::Signal2< void, float, bool > event
Definition: m2_pad.h:37
virtual float pressure() const
Definition: m2_pad.h:41
virtual void set_color(uint32_t rgba)
Definition: m2_pad.h:42
PBD::Signal0< void > released
Definition: m2_pad.h:35
virtual void set_value(uint16_t v)
Definition: m2_pad.h:45
PBD::Signal1< void, float > pressed
Definition: m2_pad.h:34
PBD::Signal1< void, float > aftertouch
Definition: m2_pad.h:36
virtual uint16_t value() const
Definition: m2_pad.h:40
void set_value(uint16_t v)
Definition: m2_pad.h:80
void set_color(uint32_t rgba)
Definition: m2_pad.h:71
unsigned int _cnt
Definition: m2_pad.h:140
uint32_t _rgba
Definition: m2_pad.h:141
float pressure() const
Definition: m2_pad.h:69
void color(uint8_t &r, uint8_t &g, uint8_t &b) const
Definition: m2_pad.h:73
uint16_t value() const
Definition: m2_pad.h:68
uint16_t hist[4]
Definition: m2_pad.h:139