LMMS
Loading...
Searching...
No Matches
midimapper.cpp
Go to the documentation of this file.
1
2#include <rtosc/ports.h>
3#include <cstring>
4#include <algorithm>
5#include <map>
6#include <sstream>
7#include <deque>
8#include <utility>
9
10#include <cassert>
11#include <rtosc/miditable.h>
12
13using namespace rtosc;
14using std::string;
15using std::get;
16using std::tuple;
17using std::make_tuple;
18
19/********************
20 * Helper Templates *
21 ********************/
22
23template<class T, class U>
24bool has_t(const T &t, const U&u)
25{return t.find(u) != t.end();}
26
27template<class T, class U>
28bool has2(const T &t, const U&u) {
29 for(const U&uu:t)
30 if(uu==u)
31 return true;
32 return false;
33}
34template<class T,class U>
35int getInd(const T&t,const U&u){
36 int i=0;
37 for(const U&uu:t) {
38 if(uu==u)
39 return i;
40 else
41 i++;
42 }
43 return -1;
44}
45
46/***********
47 * Storage *
48 ***********/
49
51{
52 for(int i=0; i<mapping.size(); ++i)
53 {
54 if(std::get<0>(mapping[i]) == ID)
55 {
56 bool coarse = std::get<1>(mapping[i]);
57 int ind = std::get<2>(mapping[i]);
58 if(coarse)
59 values[ind] = (val<<7)|(values[ind]&0x7f);
60 else
61 values[ind] = val|(values[ind]&0x3f80);
62 callbacks[ind](values[ind],write);
63 return true;
64 }
65 }
66 return false;
67}
68
69//TODO try to change O(n^2) algorithm to O(n)
71{
72 //XXX this method is SUPER error prone
73 for(int i=0; i<values.size(); ++i)
74 values[i] = 0;
75
76 for(int i=0; i<mapping.size(); ++i) {
77 for(int j=0; j<storage.mapping.size(); ++j) {
78 if(std::get<0>(mapping[i]) == std::get<0>(storage.mapping[j])) {
79 bool coarse_src = std::get<1>(storage.mapping[j]);
80 int ind_src = std::get<2>(storage.mapping[j]);
81
82 bool coarse_dest = std::get<1>(mapping[i]);
83 int ind_dest = std::get<2>(mapping[i]);
84
85 int val = 0;
86 //Extract
87 if(coarse_src)
88 val = storage.values[ind_src]>>7;
89 else
90 val = storage.values[ind_src]&0x7f;
91
92 //Blit
93 if(coarse_dest)
94 values[ind_dest] = (val<<7)|(values[ind_dest]&0x7f);
95 else
96 values[ind_dest] = val|(values[ind_dest]&0x3f80);
97 }
98 }
99 }
100}
101
103{
104 MidiMapperStorage *nstorage = new MidiMapperStorage();
105 nstorage->values = values.sized_clone();
106 nstorage->mapping = mapping.clone();
107 nstorage->callbacks = callbacks.clone();
108 return nstorage;
109}
110
111int MidiBijection::operator()(float x) const {
112 if(mode == 0)
113 return ((x-min)/(max-min))*(1<<14);
114 else
115 return 0;
116}
117
118float MidiBijection::operator()(int x) const {
119 if(mode == 0)
120 return x/((1<<14)*1.0)*(max-min)+min;
121 else
122 return 0;
123}
124
125
126/************************
127 * Non realtime portion *
128 ************************/
132
133void MidiMappernRT::map(const char *addr, bool coarse)
134{
135 for(auto x:learnQueue)
136 if(x.first == addr && x.second == coarse)
137 return;
138
139 unMap(addr, coarse);
140 learnQueue.push_back(std::make_pair(addr,coarse));
141 char buf[1024];
142 rtosc_message(buf, 1024, "/midi-learn/midi-add-watch","");
143 rt_cb(buf);
144}
145
147{
148 MidiBijection bi;
149 const auto &meta = port.meta();
150 if(meta.find("min") == meta.end() ||
151 meta.find("max") == meta.end()) {
152 printf("Rtosc-MIDI: Cannot Learn address = <%s>\n", addr.c_str());
153 printf("Rtosc-MIDI: There are no min/max fields\n");
154 return NULL;
155 }
156 bi.mode = 0;
157 bi.min = atof(port.meta()["min"]);
158 bi.max = atof(port.meta()["max"]);
159 char type = 'f';
160 if(strstr(port.name, ":i"))
161 type = 'i';
162 std::function<void(int16_t, MidiMapperStorage::write_cb cb)> tmp =
164 float out = bi(x);
165 //printf("in = %d out = %f\n", x, out);
166 char buf[1024];
167 if(type == 'f')
168 rtosc_message(buf, 1024, addr.c_str(), "f", out);
169 else
170 rtosc_message(buf, 1024, addr.c_str(), "i", (int)out);
171 cb(buf);
172 };
173 if(bi.min == 0 && bi.max == 127 && type =='i')
174 tmp = [bi,addr,type](int16_t x, MidiMapperStorage::write_cb cb) {
175 //printf("special case in = %x out = %d\n", x, 0x7f&(x>>7));
176 char buf[1024];
177 rtosc_message(buf, 1024, addr.c_str(), "i", 0x7f&(x>>7));
178 cb(buf);
179 };
180
181 MidiMapperStorage *nstorage = new MidiMapperStorage();
182 if(storage) {
183 //XXX not quite
184 nstorage->values = storage->values.one_larger();
185 nstorage->mapping = storage->mapping.clone();//insert(std::make_tuple(ID, true, storage->callbacks.size()));
186 nstorage->callbacks = storage->callbacks.insert(tmp);
187 } else {
188 nstorage->values = nstorage->values.insert(0);
189 nstorage->mapping = nstorage->mapping.clone();//insert(std::make_tuple(ID, true, 0));
190 nstorage->callbacks = nstorage->callbacks.insert(tmp);
191 }
192 inv_map[addr] = std::make_tuple(nstorage->callbacks.size()-1, -1,-1,bi);
193 return nstorage;
194}
195
196void MidiMappernRT::addNewMapper(int ID, const Port &port, std::string addr)
197{
198 MidiBijection bi;
199 bi.mode = 0;
200 bi.min = atof(port.meta()["min"]);
201 bi.max = atof(port.meta()["max"]);
202 char type = 'f';
203 if(strstr(port.name, ":i"))
204 type = 'i';
205 //printf("ADDING TYPE %c\n", type);
206 auto tmp = [bi,addr,type](int16_t x, MidiMapperStorage::write_cb cb) {
207 float out = bi(x);
208 //printf("in = %d out = %f\n", x, out);
209 char buf[1024];
210 if(type == 'f')
211 rtosc_message(buf, 1024, addr.c_str(), "f", out);
212 else
213 rtosc_message(buf, 1024, addr.c_str(), "i", (int)out);
214
215 cb(buf);
216 };
217
218 MidiMapperStorage *nstorage = new MidiMapperStorage();
219 if(storage) {
220 //XXX not quite
221 nstorage->values = storage->values.one_larger();
222 nstorage->mapping = storage->mapping.insert(std::make_tuple(ID, true, storage->callbacks.size()));
223 nstorage->callbacks = storage->callbacks.insert(tmp);
224 } else {
225 nstorage->values = nstorage->values.insert(0);
226 nstorage->mapping = nstorage->mapping.insert(std::make_tuple(ID, true, 0));
227 nstorage->callbacks = nstorage->callbacks.insert(tmp);
228 }
229 storage = nstorage;
230 inv_map[addr] = std::make_tuple(storage->callbacks.size()-1, ID,-1,bi);
231
232 char buf[1024];
233 rtosc_message(buf, 1024, "/midi-learn/midi-bind", "b", sizeof(storage), &storage);
234 rt_cb(buf);
235}
236
237void MidiMappernRT::addFineMapper(int ID, const Port &port, std::string addr)
238{
239 (void) port;
240 //TODO asserts
241 //Bijection already created
242 //Coarse node already active
243 //Value already allocated
244
245 //Find mapping
246 int mapped_ID = std::get<0>(inv_map[addr]);
247 std::get<2>(inv_map[addr]) = ID;
248 MidiMapperStorage *nstorage = new MidiMapperStorage();
249 nstorage->values = storage->values.sized_clone();
250 nstorage->mapping = storage->mapping.insert(std::make_tuple(ID, false, mapped_ID));
251 nstorage->callbacks = storage->callbacks.insert(storage->callbacks[mapped_ID]);
252 storage = nstorage;
253}
254
256{
257 MidiMapperStorage::TinyVector<tuple<int, bool, int>> nmapping(m.mapping.size()-1);
258 int j=0;
259 for(int i=0; i<m.mapping.size(); i++)
260 if(get<0>(m.mapping[i]) != ID)
261 nmapping[j++] = m.mapping[i];
262 assert(j == nmapping.size());
263 m.mapping = nmapping;
264}
265
267{
268 if(learnQueue.empty())
269 return;
270 std::string addr = std::get<0>(learnQueue.front());
271 bool coarse = std::get<1>(learnQueue.front());
272
273 learnQueue.pop_front();
275 const rtosc::Port *p = base_ports->apropos(addr.c_str());
276 assert(p);
277
278 MidiMapperStorage *nstorage;
279 if(inv_map.find(addr) == inv_map.end())
280 nstorage = generateNewBijection(*p, addr);
281 else
282 nstorage = storage->clone();
283
284 auto imap = inv_map[addr];
285 int mapped_ID = std::get<0>(imap);
286 nstorage->mapping = nstorage->mapping.insert(make_tuple(ID, coarse, mapped_ID));
287
288 if(coarse) {
289 if(get<1>(imap) != -1)
290 killMap(get<1>(imap), *nstorage);
291 inv_map[addr] = make_tuple(get<0>(imap), ID, get<2>(imap), get<3>(imap));
292 } else {
293 if(get<2>(imap) != -1)
294 killMap(get<1>(imap), *nstorage);
295 inv_map[addr] = make_tuple(get<0>(imap), get<1>(imap), ID, get<3>(imap));
296 }
297 storage = nstorage;
298
299 //TODO clean up unused value and callback objects
300
301 char buf[1024];
302 rtosc_message(buf, 1024, "/midi-learn/midi-bind", "b", sizeof(storage), &storage);
303 rt_cb(buf);
304};
305
306void MidiMappernRT::unMap(const char *addr, bool coarse)
307{
308 //printf("Unmapping('%s',%d)\n",addr,coarse);
309 if(inv_map.find(addr) == inv_map.end())
310 return;
311 auto imap = inv_map[addr];
312
313 int kill_id = -1;
314 if(coarse) {
315 kill_id = get<1>(imap);
316 inv_map[addr] = make_tuple(get<0>(imap), -1, get<2>(imap), get<3>(imap));
317 } else {
318 kill_id = get<2>(imap);
319 inv_map[addr] = make_tuple(get<0>(imap), get<1>(imap), -1, get<3>(imap));
320 }
321
322 {
323 auto tmp = inv_map[addr];
324 if(get<1>(tmp) == -1 && get<2>(tmp) == -1)
325 inv_map.erase(addr);
326 }
327
328 if(kill_id == -1)
329 return;
330
331
332
333 MidiMapperStorage *nstorage = storage->clone();
334 killMap(kill_id, *nstorage);
335 storage = nstorage;
336
337 //TODO clean up unused value and callback objects
338
339 char buf[1024];
340 rtosc_message(buf, 1024, "/midi-learn/midi-bind", "b", sizeof(storage), &storage);
341 rt_cb(buf);
342}
343
344void MidiMappernRT::delMapping(int ID, bool coarse, const char *addr){
345 (void) ID;
346 (void) coarse;
347 (void) addr;
348};
349void MidiMappernRT::replaceMapping(int, bool, const char *){};
350
352{
354 learnQueue.clear();
355 inv_map.clear();
356 char buf[1024];
357 rtosc_message(buf, 1024, "/midi-learn/midi-bind", "b", sizeof(storage), &storage);
358 rt_cb(buf);
359}
360
361
362
363std::map<std::string, std::string> MidiMappernRT::getMidiMappingStrings(void)
364{
365 std::map<std::string, std::string> result;
366 for(auto s:inv_map)
367 result[s.first] = getMappedString(s.first);
368 char ID = 'A';
369 for(auto s:learnQueue)
370 {
371 if(s.second == false)
372 result[s.first] += std::string(":")+ID++;
373 else
374 result[s.first] = ID++;
375 }
376 return result;
377}
378
379//unclear if this should be be here as a helper or not
380std::string MidiMappernRT::getMappedString(std::string addr)
381{
382 std::stringstream out;
383 //find coarse
384 if(has_t(inv_map,addr)) {
385 if(std::get<1>(inv_map[addr]) != -1)
387 }else if(has2(learnQueue, make_pair(addr,true)))
388 out << getInd(learnQueue,std::make_pair(addr,true));
389 //find Fine
390 if(has_t(inv_map,addr)) {
391 if(std::get<2>(inv_map[addr]) != -1)
392 out << ":" << std::get<2>(inv_map[addr]);
393 } else if(has2(learnQueue, make_pair(addr,false)))
394 out << getInd(learnQueue,std::make_pair(addr,false));
395
396 return out.str();
397}
398
400{
401 return std::get<3>(inv_map[s]);
402}
403
404void MidiMappernRT::snoop(const char *msg)
405{
406 if(inv_map.find(msg) != inv_map.end())
407 {
408 auto apple = inv_map[msg];
410 float value = 0;
411 std::string args = rtosc_argument_string(msg);
412 if(args == "f")
414 else if(args == "i")
416 else if(args == "T")
417 value = 1.0;
418 else if(args == "F")
419 value = 0.0;
420 else
421 return;
422
423 int new_midi = bi(value);
424 //printf("--------------------------------------------\n");
425 //printf("msg = '%s'\n", msg);
426 //printf("--------------------------------------------\n");
427 //printf("new midi value: %f->'%x'\n", value, new_midi);
428 if(std::get<1>(apple) != -1)
429 apply_high(new_midi,std::get<1>(apple));
430 if(std::get<2>(apple) != -1)
431 apply_low(new_midi,std::get<2>(apple));
432 }
433};
434
435void MidiMappernRT::apply_high(int v, int ID) { apply_midi(v>>7,ID); }
436void MidiMappernRT::apply_low(int v, int ID) { apply_midi(0x7f&v,ID);}
438{
439 char buf[1024];
440 rtosc_message(buf,1024,"/virtual_midi_cc","iii",0,val,ID);
441 rt_cb(buf);
442}
443
444void MidiMappernRT::setBounds(const char *str, float low, float high)
445{
446 if(inv_map.find(str) == inv_map.end())
447 return;
448 string addr = str;
449 auto imap = inv_map[str];
450 auto newBi = MidiBijection{0,low,high};
451 inv_map[str] = make_tuple(get<0>(imap),get<1>(imap),get<2>(imap),newBi);
452 MidiMapperStorage *nstorage = storage->clone();
453
454 nstorage->callbacks[get<0>(imap)] = [newBi,addr](int16_t x, MidiMapperStorage::write_cb cb) {
455 float out = newBi(x);
456 char buf[1024];
457 rtosc_message(buf, 1024, addr.c_str(), "f", out);
458 cb(buf);
459 };
460
461 storage = nstorage;
462
463 char buf[1024];
464 rtosc_message(buf, 1024, "/midi-learn/midi-bind", "b", sizeof(storage), &storage);
465 rt_cb(buf);
466}
467
468std::tuple<float,float,float,float> MidiMappernRT::getBounds(const char *str)
469{
470 const rtosc::Port *p = base_ports->apropos(str);
471 assert(p);
472 float min_val = atof(p->meta()["min"]);
473 float max_val = atof(p->meta()["max"]);
474 if(inv_map.find(str) != inv_map.end()) {
475 auto elm = std::get<3>(inv_map[str]);
476 return std::make_tuple(min_val, max_val,elm.min,elm.max);
477 }
478 return std::make_tuple(min_val, max_val,-1.0f,-1.0f);
479}
480
481bool MidiMappernRT::has(std::string addr)
482{
483 return inv_map.find(addr) != inv_map.end();
484}
485
486bool MidiMappernRT::hasPending(std::string addr)
487{
488 for(auto s:learnQueue)
489 if(s.first == addr)
490 return true;
491 return false;
492}
493
494bool MidiMappernRT::hasCoarse(std::string addr)
495{
496 if(!has(addr))
497 return false;
498 auto e = inv_map[addr];
499 return std::get<1>(e) != -1;
500}
501
502bool MidiMappernRT::hasFine(std::string addr)
503{
504 if(!has(addr))
505 return false;
506 auto e = inv_map[addr];
507 return std::get<2>(e) != -1;
508}
509
511{
512 for(auto s:learnQueue)
513 if(s.first == addr && s.second)
514 return true;
515 return false;
516}
517
518bool MidiMappernRT::hasFinePending(std::string addr)
519{
520 for(auto s:learnQueue)
521 if(s.first == addr && !s.second)
522 return true;
523 return false;
524}
525
526int MidiMappernRT::getCoarse(std::string addr)
527{
528 if(!has(addr))
529 return -1;
530 auto e = inv_map[addr];
531 return std::get<1>(e);
532}
533
534int MidiMappernRT::getFine(std::string addr)
535{
536 if(!has(addr))
537 return -1;
538 auto e = inv_map[addr];
539 return std::get<2>(e);
540}
541
542/*****************
543 * Realtime code *
544 *****************/
545
549void MidiMapperRT::setBackendCb(std::function<void(const char*)> cb) {backend = cb;}
550void MidiMapperRT::setFrontendCb(std::function<void(const char*)> cb) {frontend = cb;}
551void MidiMapperRT::handleCC(int ID, int val) {
552 //printf("handling CC(%d,%d){%d,%d,%d}\n", ID, val, (int)storage, pending.has(ID), watchSize);
553 if((!storage || !storage->handleCC(ID, val, backend)) && !pending.has(ID) && watchSize) {
554 watchSize--;
555 pending.insert(ID);
556 char msg[1024];
557 rtosc_message(msg, 1024, "/midi-use-CC", "i", ID);
558 frontend(msg);
559 }
560}
563
565 {"midi-add-watch",0,0, [](msg_t, RtData&d)
566 {
567 auto midi = (MidiMapperRT*)d.obj;
568 midi->addWatch();}},
569 {"midi-remove-watch",0,0, [](msg_t, RtData&d)
570 {
571 auto midi = (MidiMapperRT*)d.obj;
572 midi->remWatch();}},
573 {"midi-bind:b","",0, [](msg_t msg, RtData&d)
574 {
575 auto &midi = *(MidiMapperRT*)d.obj;
576 midi.pending.pop();
577 MidiMapperStorage *nstorage =
579 if(midi.storage) {
580 nstorage->cloneValues(*midi.storage);
581 midi.storage = nstorage;
582 } else
583 midi.storage = nstorage;}}
584};
585
586//Depricated
588 return Port{"midi-add-watch","",0, [this](msg_t, RtData&) {
589 this->addWatch();
590 }};
591}
593 return Port{"midi-remove-watch","",0, [this](msg_t, RtData&) {
594 this->remWatch();
595 }};
596}
598 return Port{"midi-bind:b","",0, [this](msg_t msg, RtData&) {
599 pending.pop();
600 MidiMapperStorage *nstorage =
602 if(storage) {
603 nstorage->cloneValues(*storage);
604 storage = nstorage;
605 } else
606 storage = nstorage;
607 //TODO memory deallocation
608 }};
609}
#define NULL
Definition CarlaBridgeFormat.cpp:30
assert(0)
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
Definition miditable.h:155
void setBackendCb(std::function< void(const char *)> cb)
Definition midimapper.cpp:549
MidiMapperRT(void)
Definition midimapper.cpp:546
static const Ports ports
Definition miditable.h:169
void setFrontendCb(std::function< void(const char *)> cb)
Definition midimapper.cpp:550
void addWatch(void)
Definition midimapper.cpp:561
void remWatch(void)
Definition midimapper.cpp:562
std::function< void(const char *)> frontend
Definition miditable.h:219
Port bindPort(void)
Definition midimapper.cpp:597
PendingQueue pending
Definition miditable.h:215
Port removeWatchPort(void)
Definition midimapper.cpp:592
void handleCC(int ID, int val)
Definition midimapper.cpp:551
MidiMapperStorage * storage
Definition miditable.h:216
Port addWatchPort(void)
Definition midimapper.cpp:587
std::function< void(const char *)> backend
Definition miditable.h:218
unsigned watchSize
Definition miditable.h:217
Definition miditable.h:53
TinyVector insert(const T &t_)
Definition miditable.h:62
int size(void) const
Definition miditable.h:70
TinyVector clone(void)
Definition miditable.h:68
Definition miditable.h:49
TinyVector< int > values
Definition miditable.h:79
MidiMapperStorage * clone(void)
Definition midimapper.cpp:102
TinyVector< callback_t > callbacks
Definition miditable.h:77
std::function< void(const char *)> write_cb
Definition miditable.h:73
bool handleCC(int ID, int val, write_cb write)
Definition midimapper.cpp:50
TinyVector< std::tuple< int, bool, int > > mapping
Definition miditable.h:76
void cloneValues(const MidiMapperStorage &storage)
Definition midimapper.cpp:70
int getCoarse(std::string addr)
Definition midimapper.cpp:526
void apply_low(int v, int ID)
Definition midimapper.cpp:436
void addNewMapper(int ID, const Port &port, std::string addr)
Definition midimapper.cpp:196
std::map< std::string, std::tuple< int, int, int, MidiBijection > > inv_map
Definition miditable.h:147
bool hasFinePending(std::string addr)
Definition midimapper.cpp:518
bool has(std::string addr)
Definition midimapper.cpp:481
bool hasFine(std::string addr)
Definition midimapper.cpp:502
const Ports * base_ports
Definition miditable.h:151
MidiMappernRT(void)
Definition midimapper.cpp:129
std::function< void(const char *)> rt_cb
Definition miditable.h:149
MidiBijection getBijection(std::string s)
Definition midimapper.cpp:399
void delMapping(int ID, bool coarse, const char *addr)
Definition midimapper.cpp:344
MidiMapperStorage * storage
Definition miditable.h:150
MidiMapperStorage * generateNewBijection(const Port &port, std::string)
Definition midimapper.cpp:146
void map(const char *addr, bool coarse=true)
Definition midimapper.cpp:133
void useFreeID(int ID)
Definition midimapper.cpp:266
void snoop(const char *msg)
Definition midimapper.cpp:404
bool hasPending(std::string addr)
Definition midimapper.cpp:486
void setBounds(const char *str, float low, float high)
Definition midimapper.cpp:444
std::map< std::string, std::string > getMidiMappingStrings(void)
Definition midimapper.cpp:363
int getFine(std::string addr)
Definition midimapper.cpp:534
void replaceMapping(int, bool, const char *)
Definition midimapper.cpp:349
std::deque< std::pair< std::string, bool > > learnQueue
Definition miditable.h:148
void apply_high(int v, int ID)
Definition midimapper.cpp:435
void addFineMapper(int ID, const Port &port, std::string addr)
Definition midimapper.cpp:237
std::tuple< float, float, float, float > getBounds(const char *str)
Definition midimapper.cpp:468
void unMap(const char *addr, bool coarse)
Definition midimapper.cpp:306
std::string getMappedString(std::string addr)
Definition midimapper.cpp:380
bool hasCoarsePending(std::string addr)
Definition midimapper.cpp:510
void clear(void)
Definition midimapper.cpp:351
void apply_midi(int val, int ID)
Definition midimapper.cpp:437
bool hasCoarse(std::string addr)
Definition midimapper.cpp:494
* e
Definition inflate.c:1404
unsigned * m
Definition inflate.c:1559
struct huft * t
Definition inflate.c:943
register unsigned j
Definition inflate.c:1576
unsigned v[N_MAX]
Definition inflate.c:1584
unsigned d
Definition inflate.c:940
struct huft * u[BMAX]
Definition inflate.c:1583
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned x[BMAX+1]
Definition inflate.c:1586
#define U(x)
Definition fmopl.c:132
static PuglViewHint int value
Definition pugl.h:1708
int val
Definition jpeglib.h:956
float out
Definition lilv_test.c:1461
short int16_t
Definition mid.cpp:96
bool has_t(const T &t, const U &u)
Definition midimapper.cpp:24
void killMap(int ID, MidiMapperStorage &m)
Definition midimapper.cpp:255
int getInd(const T &t, const U &u)
Definition midimapper.cpp:35
bool has2(const T &t, const U &u)
Definition midimapper.cpp:28
const char * msg
Definition missing_descriptor.c:20
Definition globals.h:37
const char * msg_t
Definition ports.h:48
static char tmp[256]
Definition undo-history.cpp:80
osc_element< Index, rtMsg< Types... > >::type get(rtMsg< Types... > &Tuple)
Definition typed-message.h:142
const char * rtosc_argument_string(const char *msg)
Definition rtosc.c:11
size_t rtosc_message(char *buffer, size_t len, const char *address, const char *arguments,...)
Definition rtosc.c:161
rtosc_arg_t rtosc_argument(const char *msg, unsigned idx)
Definition rtosc.c:732
Definition miditable.h:90
float max
Definition miditable.h:93
int mode
Definition miditable.h:91
int operator()(float x) const
Definition midimapper.cpp:111
float min
Definition miditable.h:92
Definition ports.h:99
Definition ports.h:161
data object for the dispatch routine
Definition ports.h:55
uint8_t * data
Definition rtosc.h:43
int32_t i
Definition rtosc.h:47
rtosc_blob_t b
Definition rtosc.h:55
float f
Definition rtosc.h:49
uch * p
Definition crypt.c:594
int result
Definition process.c:1455
#define void
Definition unzip.h:396