Real Time Open Sound Control librtosc
miditable.h
1 /*
2  * Copyright (c) 2012 Mark McCurry
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 #ifndef RTOSC_MIDITABLE_H
25 #define RTOSC_MIDITABLE_H
26 
27 #include <rtosc/ports.h>
28 #include <string.h>
29 #include <algorithm>
30 #include <map>
31 #include <sstream>
32 #include <deque>
33 #include <utility>
34 #include <cassert>
35 
36 namespace rtosc {
49 {
50  public:
51  //Almost immutable short vector class
52  template<class T>
53  class TinyVector {
54  int n;
55  T *t;
56  public:
57  TinyVector(void):n(0),t(0){}
58  TinyVector(int i):n(i),t(new T[i]){}
59  T&operator[](int i) {assert(i>=0 && i<n);return t[i];}
60  T operator[](int i) const {assert(i>=0 && i<n);return t[i];}
61 
62  TinyVector insert(const T &t_)
63  {TinyVector next(n+1); for(int i=0;i<n; ++i) next.t[i]=t[i]; next.t[n] = t_;return std::move(next);}
64  TinyVector one_larger(void)
65  {TinyVector next(n+1); for(int i=0;i<n + 1; ++i) next.t[i]=0; return std::move(next);}
66  TinyVector sized_clone(void)
67  {TinyVector next(n); for(int i=0;i<n; ++i) next.t[i]=0; return std::move(next);}
68  TinyVector clone(void)
69  {TinyVector next(n); for(int i=0;i<n; ++i) next.t[i]=t[i]; return std::move(next);}
70  int size(void) const{return n;}
71  };
72 
73  typedef std::function<void(const char*)> write_cb;
74  typedef std::function<void(int16_t,write_cb)> callback_t;
75  //RT Read Only
76  TinyVector<std::tuple<int, bool, int>> mapping;//CC->{coarse, val-cb offset}
77  TinyVector<callback_t> callbacks;
78  //RT RW
79  TinyVector<int> values;
80 
81  bool handleCC(int ID, int val, write_cb write);
82 
83  //TODO try to change O(n^2) algorithm to O(n)
84  void cloneValues(const MidiMapperStorage &storage);
85 
86  MidiMapperStorage *clone(void);
87 };
88 
90 {
91  int mode;//0:linear,1:log
92  float min;
93  float max;
94  int operator()(float x) const;
95  float operator()(int x) const;
96 };
97 
99 {
100  public:
101  MidiMappernRT(void);
102  void map(const char *addr, bool coarse = true);
103 
104  MidiMapperStorage *generateNewBijection(const Port &port, std::string);
105 
106  void addNewMapper(int ID, const Port &port, std::string addr);
107 
108  void addFineMapper(int ID, const Port &port, std::string addr);
109 
110  void useFreeID(int ID);
111 
112  void unMap(const char *addr, bool coarse);
113 
114  void delMapping(int ID, bool coarse, const char *addr);
115  void replaceMapping(int, bool, const char *);
116 
117  void clear(void);
118 
119  std::map<std::string, std::string> getMidiMappingStrings(void);
120 
121  //unclear if this should be be here as a helper or not
122  std::string getMappedString(std::string addr);
123 
124  MidiBijection getBijection(std::string s);
125 
126  void snoop(const char *msg);
127 
128  void apply_high(int v, int ID);
129  void apply_low(int v, int ID);
130  void apply_midi(int val, int ID);
131 
132  void setBounds(const char *str, float low, float high);
133 
134  std::tuple<float,float,float,float> getBounds(const char *str);
135 
136  bool has(std::string addr);
137  bool hasPending(std::string addr);
138  bool hasCoarse(std::string addr);
139  bool hasFine(std::string addr);
140  bool hasCoarsePending(std::string addr);
141  bool hasFinePending(std::string addr);
142  int getCoarse(std::string addr);
143  int getFine(std::string addr);
144 
145  //(Location, Coarse, Fine, Bijection)
146  std::map<std::string, std::tuple<int, int, int, MidiBijection>> inv_map;
147  std::deque<std::pair<std::string,bool>> learnQueue;
148  std::function<void(const char *)> rt_cb;
149  MidiMapperStorage *storage;
150  const Ports *base_ports;
151 };
152 
154 {
155  public:
156  MidiMapperRT(void);
157  void setBackendCb(std::function<void(const char*)> cb);
158  void setFrontendCb(std::function<void(const char*)> cb);
159  void handleCC(int ID, int val);
160  void addWatch(void);
161  void remWatch(void);
162 
163  //Depricated
164  Port addWatchPort(void);
165  Port removeWatchPort(void);
166  Port bindPort(void);
167 
168  static const Ports ports;
169 
170  //Fixed upper bounded size set of integer IDs
172  {
173  public:
174  PendingQueue()
175  :pos_r(0), pos_w(0), size(0)
176  {
177  for(int i=0; i<32; ++i)
178  vals[i] = -1;
179  }
180  void insert(int x)
181  {
182  if(has(x) || size > 31)
183  return;
184  vals[pos_w] = x;
185  size++;
186  pos_w = (pos_w+1)%32;
187  }
188  void pop(void)
189  {
190  if(size == 0)
191  return;
192  size--;
193  vals[pos_r] = -1;
194  pos_r = (1+pos_r)%32;
195  }
196  bool has(int x)
197  {
198  for(int i=0; i<32; ++i)
199  if(vals[i] == x)
200  return true;
201  return false;
202  }
203  int vals[32];
204  int pos_r;
205  int pos_w;
206  int size;
207 
208  };
209 
210 
211  /***************
212  * Member Data *
213  ***************/
214  PendingQueue pending;
215  MidiMapperStorage *storage;
216  unsigned watchSize;
217  std::function<void(const char*)> backend;
218  std::function<void(const char*)> frontend;
219 };
220 
221 struct MidiAddr
222 {
223  //The midi values that map to the specified action
224  uint8_t ch, ctl;
225 
226  //The type of the event 'f', 'i', 'T', 'c'
227  char type;
228  //The path of the event
229  char *path;
230  //The conversion function for 'f' types
231  const char *conversion;
232 };
233 
234 
240 {
241  public:
242 
243  const Ports &dispatch_root;
244  short unhandled_ch;
245  short unhandled_ctl;
246  char *unhandled_path;
247 
248  void (*error_cb)(const char *, const char *);
249  void (*event_cb)(const char *);
250  void (*modify_cb)(const char *, const char *, const char *, int, int);
251 
252  MidiTable(const Ports &_dispatch_root);
253  ~MidiTable();
254 
255  bool has(uint8_t ch, uint8_t ctl) const;
256 
257  MidiAddr *get(uint8_t ch, uint8_t ctl);
258 
259  const MidiAddr *get(uint8_t ch, uint8_t ctl) const;
260 
261  bool mash_port(MidiAddr &e, const Port &port);
262 
263  void addElm(uint8_t ch, uint8_t ctl, const char *path);
264 
265  void check_learn(void);
266 
267  void learn(const char *s);
268 
269  void clear_entry(const char *s);
270 
271  void process(uint8_t ch, uint8_t ctl, uint8_t val);
272 
273  Port learnPort(void);
274  Port unlearnPort(void);
275  Port registerPort(void);
276 
277  //TODO generalize to an addScalingFunction() system
278  static float translate(uint8_t val, const char *meta);
279 
280  private:
281  class MidiTable_Impl *impl;
282 };
283 
284 };
285 #endif
Port in rtosc dispatching hierarchy.
Definition: ports.h:96
Table of midi mappings - Deprecated.
Definition: miditable.h:239
Definition: miditable.h:153
Definition: miditable.h:53
Module Overview.
Definition: miditable.h:48
Definition: miditable.h:98
Ports - a dispatchable collection of Port entries.
Definition: ports.h:157
Definition: miditable.h:221
Definition: miditable.h:171
Collection of functions for ports.
Definition: miditable.h:89