static osc_data_t * oscmidi_engine_off_cb(osc_data_t *buf, osc_data_t *end, CMC_Blob_Event *bev) { osc_data_t *buf_ptr = buf; osc_data_t *itm = NULL; OSC_MIDI_Format format = config.oscmidi.format; uint_fast8_t multi = config.oscmidi.multi; uint_fast8_t use_mpe = config.oscmidi.mpe; if(multi) { buf_ptr = osc_start_bundle_item(buf_ptr, end, &itm); buf_ptr = osc_set_path(buf_ptr, end, config.oscmidi.path); buf_ptr = osc_set_fmt(buf_ptr, end, oscmidi_fmt_1[format]); } uint8_t key; uint8_t ch; midi_rem_key(oscmidi_hash, bev->sid, &key, &ch); if(use_mpe) mpe_release(&mpe, bev->gid, ch); // serialize buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_NOTE_OFF, key, 0x7f); if(multi) buf_ptr = osc_end_bundle_item(buf_ptr, end, itm); return buf_ptr; }
static osc_data_t * oscmidi_engine_on_cb(osc_data_t *buf, osc_data_t *end, CMC_Blob_Event *bev) { osc_data_t *buf_ptr = buf; osc_data_t *itm = NULL; OSC_MIDI_Format format = config.oscmidi.format; uint_fast8_t multi = config.oscmidi.multi; uint_fast8_t use_mpe = config.oscmidi.mpe; OSC_MIDI_Group *group = &oscmidi_groups[bev->gid]; OSC_MIDI_Mapping mapping = group->mapping; if(multi) { buf_ptr = osc_start_bundle_item(buf_ptr, end, &itm); buf_ptr = osc_set_path(buf_ptr, end, config.oscmidi.path); if( (mapping == OSC_MIDI_MAPPING_CONTROL_CHANGE) && (group->control <= 0xd) ) buf_ptr = osc_set_fmt(buf_ptr, end, oscmidi_fmt_4[format]); else buf_ptr = osc_set_fmt(buf_ptr, end, oscmidi_fmt_3[format]); } uint8_t ch; if(use_mpe) ch = mpe_acquire(&mpe, bev->gid); else ch = bev->gid; float X = group->offset + bev->x*group->range; uint8_t key = floor(X); midi_add_key(oscmidi_hash, bev->sid, key, ch); uint16_t bend =(X - key)*mul[bev->gid] + 0x1fff; uint16_t eff = bev->y * 0x3fff; // serialize buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_NOTE_ON, key, 0x7f); buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_PITCH_BEND, bend & 0x7f, bend >> 7); switch(mapping) { case OSC_MIDI_MAPPING_NOTE_PRESSURE: buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_NOTE_PRESSURE, key, eff >> 7); break; case OSC_MIDI_MAPPING_CHANNEL_PRESSURE: buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_CHANNEL_PRESSURE, eff >> 7, 0x0); break; case OSC_MIDI_MAPPING_CONTROL_CHANGE: if(group->control <= 0xd) buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_CONTROL_CHANGE, group->control | MIDI_LSV, eff & 0x7f); buf_ptr = oscmidi_serialize(buf_ptr, end, format, ch, MIDI_STATUS_CONTROL_CHANGE, group->control | MIDI_MSV, eff >> 7); break; } if(multi) buf_ptr = osc_end_bundle_item(buf_ptr, end, itm); return buf_ptr; }
static osc_data_t * oscmidi_serialize(osc_data_t *buf, osc_data_t *end, OSC_MIDI_Format format, uint8_t channel, uint8_t status, uint8_t dat1, uint8_t dat2) { osc_data_t *buf_ptr = buf; osc_data_t *itm = NULL; uint_fast8_t multi = config.oscmidi.multi; if(!multi) { buf_ptr = osc_start_bundle_item(buf_ptr, end, &itm); buf_ptr = osc_set_path(buf_ptr, end, config.oscmidi.path); buf_ptr = osc_set_fmt(buf_ptr, end, oscmidi_fmt_1[format]); } switch(format) { case OSC_MIDI_FORMAT_MIDI: { uint8_t *M; buf_ptr = osc_set_midi_inline(buf_ptr, end, &M); if(buf_ptr) { M[0] = 0; M[1] = channel | status; M[2] = dat1; M[3] = dat2; } break; } case OSC_MIDI_FORMAT_INT32: { int32_t i = (dat2 << 16) | (dat1 << 8) | ( (channel | status) << 0); buf_ptr = osc_set_int32(buf_ptr, end, i); break; } case OSC_MIDI_FORMAT_BLOB: { uint8_t *B; buf_ptr = osc_set_blob_inline(buf_ptr, end, 3, (void **)&B); if(buf_ptr) { B[0] = channel | status; B[1] = dat1; B[2] = dat2; } break; } } if(!multi) buf_ptr = osc_end_bundle_item(buf_ptr, end, itm); return buf_ptr; }
static osc_data_t * oscmidi_engine_end_cb(osc_data_t *buf, osc_data_t *end, CMC_Frame_Event *fev) { (void)fev; osc_data_t *buf_ptr = buf; buf_ptr = osc_end_bundle(buf_ptr, end, bndl); if(cmc_engines_active + config.dump.enabled > 1) buf_ptr = osc_end_bundle_item(buf_ptr, end, pack); return buf_ptr; }
static osc_data_t * oscmidi_engine_frame_cb(osc_data_t *buf, osc_data_t *end, CMC_Frame_Event *fev) { osc_data_t *buf_ptr = buf; if(cmc_engines_active + config.dump.enabled > 1) buf_ptr = osc_start_bundle_item(buf_ptr, end, &pack); buf_ptr = osc_start_bundle(buf_ptr, end, fev->offset, &bndl); if(update_zones) { OSC_MIDI_Format format = config.oscmidi.format; uint_fast8_t multi = config.oscmidi.multi; osc_data_t *itm = NULL; for(uint8_t z=0; z<cmc_groups_n; z++) { if(multi) { buf_ptr = osc_start_bundle_item(buf_ptr, end, &itm); buf_ptr = osc_set_path(buf_ptr, end, config.oscmidi.path); buf_ptr = osc_set_fmt(buf_ptr, end, "mmmmmm"); } const zone_t *zone = &mpe.zones[z]; // define zone span buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_RPN_LSB, 0x6); buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_RPN_MSB, 0x0); buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_DATA_ENTRY, zone->span); // define zone bend range buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base+1, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_RPN_LSB, 0x0); buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base+1, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_RPN_MSB, 0x0); const uint8_t semitone_range = ceil(oscmidi_groups[z].range); buf_ptr = oscmidi_serialize(buf_ptr, end, format, zone->base+1, MIDI_STATUS_CONTROL_CHANGE, MIDI_CONTROLLER_DATA_ENTRY, semitone_range); if(multi) buf_ptr = osc_end_bundle_item(buf_ptr, end, itm); } update_zones = 0; } return buf_ptr; }
// rt static void _message_cb(const char *path, const char *fmt, const LV2_Atom_Tuple *body, void *data) { prog_t *handle = data; osc_data_t *ptr = handle->osc_ptr; const osc_data_t *end = handle->osc_end; osc_data_t *itm = NULL; if(handle->bndl_cnt) ptr = osc_start_bundle_item(ptr, end, &itm); ptr = osc_set_path(ptr, end, path); ptr = osc_set_fmt(ptr, end, fmt); const LV2_Atom *itr = lv2_atom_tuple_begin(body); for(const char *type = fmt; *type && !lv2_atom_tuple_is_end(LV2_ATOM_BODY(body), body->atom.size, itr); type++, itr = lv2_atom_tuple_next(itr)) { switch(*type) { case 'i': { ptr = osc_set_int32(ptr, end, ((const LV2_Atom_Int *)itr)->body); break; } case 'f': { ptr = osc_set_float(ptr, end, ((const LV2_Atom_Float *)itr)->body); break; } case 's': case 'S': { ptr = osc_set_string(ptr, end, LV2_ATOM_BODY_CONST(itr)); break; } case 'b': { ptr = osc_set_blob(ptr, end, itr->size, LV2_ATOM_BODY(itr)); break; } case 'h': { ptr = osc_set_int64(ptr, end, ((const LV2_Atom_Long *)itr)->body); break; } case 'd': { ptr = osc_set_double(ptr, end, ((const LV2_Atom_Double *)itr)->body); break; } case 't': { ptr = osc_set_timetag(ptr, end, ((const LV2_Atom_Long *)itr)->body); break; } case 'T': case 'F': case 'N': case 'I': { break; } case 'c': { ptr = osc_set_char(ptr, end, ((const LV2_Atom_Int *)itr)->body); break; } case 'm': { const uint8_t *src = LV2_ATOM_BODY_CONST(itr); const uint8_t dst [4] = { 0x00, // port byte itr->size >= 1 ? src[0] : 0x00, itr->size >= 2 ? src[1] : 0x00, itr->size >= 3 ? src[2] : 0x00 }; ptr = osc_set_midi(ptr, end, dst); break; } } } if(handle->bndl_cnt) ptr = osc_end_bundle_item(ptr, end, itm); handle->osc_ptr = ptr; }