Real Time Open Sound Control librtosc: include/rtosc/miditable.h Source File

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 {
48 class MidiMapperStorage
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
89 struct MidiBijection
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
98 class MidiMappernRT
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
153 class MidiMapperRT
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
171 class PendingQueue
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
239 class MidiTable
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
rtosc::MidiMapperRT
Definition: miditable.h:154
rtosc::Ports
Ports - a dispatchable collection of Port entries.
Definition: ports.h:158
rtosc::MidiAddr
Definition: miditable.h:222
rtosc::MidiBijection
Definition: miditable.h:90
rtosc::MidiMapperStorage
Module Overview.
Definition: miditable.h:49
rtosc::MidiTable
Table of midi mappings - Deprecated.
Definition: miditable.h:240
rtosc::Port
Port in rtosc dispatching hierarchy.
Definition: ports.h:96
rtosc::MidiMappernRT
Definition: miditable.h:99
ports.h
Collection of functions for ports.
rtosc::MidiMapperRT::PendingQueue
Definition: miditable.h:172
rtosc::MidiMapperStorage::TinyVector
Definition: miditable.h:53