void notifyControlChangeByName (void *mcfg, const char * cfname, unsigned char val) { struct b_midicfg * m = (struct b_midicfg *) mcfg; int x = getCCFunctionId (cfname); if (x >= 0 && m->ctrlvecF[x].fn) { controlFunctionHook(m, &m->ctrlvecF[x], val); } }
/* * 26-sep-2004/FK This is the entry point for modules that wish to register * functions that accept MIDI controller data. Functions entered through this * interface can be freely remapped by the user via configuration files. * * @param cfname The symbolic name (defined in ccFuncNames) of the reaction * implemented by the function pointed to by the f parameter. * @param f Pointer to function that acts on the controller message. */ void useMIDIControlFunction (void *mcfg, const char * cfname, void (* f) (void *, unsigned char), void *d) { struct b_midicfg * m = (struct b_midicfg *) mcfg; int x = getCCFunctionId (cfname); assert (-1 < x); if (m->ctrlUseA[x] < 128) { assignMIDIControllerFunction (m->ctrlvecA, m->ctrlUseA[x], x, f, d); } if (m->ctrlUseB[x] < 128) { assignMIDIControllerFunction (m->ctrlvecB, m->ctrlUseB[x], x, f, d); } if (m->ctrlUseC[x] < 128) { assignMIDIControllerFunction (m->ctrlvecC, m->ctrlUseC[x], x, f, d); } if ((m->ctrlvecF[x].fn != emptyControlFunction) && (m->ctrlvecF[x].fn != NULL)) { fprintf (stderr, "midi.c:WARNING, multiple allocation of control-function %s!\n", cfname); } m->ctrlvecF[x].fn = f; m->ctrlvecF[x].d = d; m->ctrlvecF[x].id = x; }
void callMIDIControlFunction (void *mcfg, const char * cfname, unsigned char val) { struct b_midicfg * m = (struct b_midicfg *) mcfg; int x = getCCFunctionId (cfname); if (x >= 0 && m->ctrlvecF[x].fn) { if (val > 127) val = 127; execControlFunction(m, &m->ctrlvecF[x], val); } }
static void formatDoc (const char *modulename, const ConfigDoc *d) { printf("Parameters for '%s':\n", modulename); while (d && d->name) { if (strlen(d->name) >= 40) { fprintf(stderr, "PROPERTY NAME IS TOO LONG -- PLEASE REPORT THIS BUG\n"); } printf(" %-40s %s%s (%s)\n", d->name, conftypenames[d->type], (getCCFunctionId(d->name)<0)?" ":"*", (strlen(d->dflt)>0)?d->dflt:"?"); if (strlen(d->desc)>0) { // TODO: word-wrap description, with indent 4 printf(" %s\n", d->desc); } d++; } printf("\n"); }
void rc_add_cfg(void *t, ConfigContext *cfg) { struct b_rc *rc = (struct b_rc*) t; #if 0 if (getCCFunctionId(cfg->name) > 0) { /* if there is a MIDI-CC function corresponding to the cfg -> use it */ // mmh. what to do with 'cfg->value' ?! // - check doc for function parameter type. // CFG_DOUBLE, CFG_FLOAT -> * 127.0 -- won't work for all though :( // CFG_INT -> mmh, keep as is ?! // CFG_TEXT -> fall though to cfg_eval() // // major rework: have all useMIDIControlFunction() /users/ // specify a target range and/or conversion function. // -> that'll also remove lots of wrapper function bloat: // eg. setDrumBreakPosition(), revControl(), setPercEnableFromMIDI(),.. etc printf (" cfg_midi(\"%s\", \"%s\")\n", cfg->name, cfg->value); return; } else #endif kvstore_store(rc->rrc, cfg->name, cfg->value); }
/* * Auxillary function to midiPrimeControllerMapping below. */ static void loadCCMap (struct b_midicfg * m, const char * cfname, int ccn, unsigned char * A, unsigned char * B, unsigned char * C) { int x = getCCFunctionId (cfname); if (!(-1 < x)) { fprintf (stderr, "Unrecognized controller function name:'%s'\n", cfname); assert (-1 < x); } if (A != NULL) { A[x] = (unsigned char) ccn; reverse_cc_map(m, x, m->rcvChA, ccn); } if (B != NULL) { B[x] = (unsigned char) ccn; reverse_cc_map(m, x, m->rcvChB, ccn); } if (C != NULL) { C[x] = (unsigned char) ccn; reverse_cc_map(m, x, m->rcvChC, ccn); } }
/* * This call configures this module. */ int midiConfig (void *mcfg, ConfigContext * cfg) { int v; int ack = 0; struct b_midicfg * m = (struct b_midicfg *) mcfg; if ((ack = getConfigParameter_ir ("midi.upper.channel", cfg, &v, 1, 16)) == 1) { m->rcvChA = v - 1; } else if ((ack = getConfigParameter_ir ("midi.lower.channel", cfg, &v, 1, 16)) == 1) { m->rcvChB = v - 1; } else if ((ack = getConfigParameter_ir ("midi.pedals.channel", cfg, &v, 1, 16)) == 1) { m->rcvChC = v - 1; } else if ((ack = getConfigParameter_ir ("midi.transpose", cfg, &v, -127, 127)) == 1) { m->transpose = v; } else if ((ack = getConfigParameter_ir ("midi.upper.transpose", cfg, &v, -127, 127)) == 1) { m->nshA = v; } else if ((ack = getConfigParameter_ir ("midi.lower.transpose", cfg, &v, -127, 127)) == 1) { m->nshB = v; } else if ((ack = getConfigParameter_ir ("midi.pedals.transpose", cfg, &v, -127, 127)) == 1) { m->nshC = v; } else if ((ack = getConfigParameter_ir ("midi.pedals.transpose.split", cfg, &v, -127, 127)) == 1) { m->nshA_PL = v; } else if ((ack = getConfigParameter_ir ("midi.lower.transpose.split", cfg, &v, -127, 127)) == 1) { m->nshA_UL = v; } else if ((ack = getConfigParameter_ir ("midi.upper.transpose.split", cfg, &v, -127, 127)) == 1) { m->nshA_U = v; } else if (strncasecmp (cfg->name, "midi.controller.reset", 21) == 0) { ack++; if (atoi(cfg->name+21)) { clearControllerMapping(m); } } /* * The syntax for this config option is: * midi.controller.{upper,lower,pedals}.<cc>=<fname> * where <cc> is a MIDI controller number, and * <fname> is the symbolic name of a controllable function. */ else if (strncasecmp (cfg->name, "midi.controller.", 16) == 0) { unsigned char * ctrlUse = m->ctrlUseA; int ccIdx = 0; // offset in cfg->name int ccChn = 0; if (strncasecmp ((cfg->name) + 16, "upper", 5) == 0) { ctrlUse = m->ctrlUseA; ccIdx = 22; ccChn = m->rcvChA; } else if (strncasecmp ((cfg->name) + 16, "lower", 5) == 0) { ctrlUse = m->ctrlUseB; ccIdx = 22; ccChn = m->rcvChB; } else if (strncasecmp ((cfg->name) + 16, "pedals", 6) == 0) { ctrlUse = m->ctrlUseC; ccIdx = 23; ccChn = m->rcvChC; } else { showConfigfileContext (cfg, "directive 'upper', 'lower' or 'pedals' expected"); } /* If the code above managed to parse a channel name... */ if (0 < ccIdx) { int ccn; /* ... and we manage to parse a controller number... */ if (sscanf ((cfg->name) + ccIdx, "%d", &ccn) == 1) { /* ...and the controller number is in the allowed range... */ if ((0 <= ccn) && (ccn < 128)) { int i = getCCFunctionId (cfg->value); if (!strcmp(cfg->value,"unmap")) { remove_CC_map(m, ccChn, ccn); } else if (-1 < i) { remove_CC_map(m, ccChn, ccn); /* Store the controller number indexed by abstract function id */ ctrlUse[i] = ccn; parseCCFlags(&(m->ctrlflg[ccChn][ccn]), cfg->value); reverse_cc_map(m, i, ccChn, ccn); ack++; } else { /* No match found for symbolic function name. */ showConfigfileContext (cfg, "name of controllable function not found"); } } else { showConfigfileContext (cfg, "controller number out of range"); } } } } return ack; }