static int64_t _read_var_value(midi_info_t *mi) { unsigned long stamp = 0; int byte; do { byte = _read_byte(mi); if (byte == -1) return -1; stamp <<= 7; stamp |= byte & 0x7F; } while ((byte & 0x80) == 0x80); return stamp; }
// Read distance in cm from LidarLite int lidar_read(int fd) { int hiVal, loVal, i=0; // send "measure" command hiVal = wiringPiI2CWriteReg8(fd, MEASURE_REG, MEASURE_VAL); if (_dbg) printf("write res=%d\n", hiVal); delay(20); // Read second byte and append with first loVal = _read_byteNZ(fd, DISTANCE_REG_LO) ; if (_dbg) printf(" Lo=%d\n", loVal); // read first byte hiVal = _read_byte(fd, DISTANCE_REG_HI) ; if (_dbg) printf ("Hi=%d ", hiVal); return ( (hiVal << 8) + loVal); }
// low level byte read void EDB::edbRead(unsigned long ee, byte* p, unsigned int recsize) { for (unsigned i = 0; i < recsize; i++) *p++ = _read_byte(ee++); }
int midi_eventout(midi_info_t *mi, snd_seq_event_t *ev) { int64_t stamp, length; int status, data; int tempo; int err; void *buf; if (_data_left(mi) == 0) return EDATA; snd_seq_ev_clear(ev); snd_seq_ev_set_fixed(ev); // We know at this point that the entire event // is within the packet, since it's illegal // to span packet boundries for events. // this makes our lives _so_ much easier. stamp = _read_var_value(mi); if (stamp < 0) return EEVENT; mi->time += stamp; snd_seq_ev_schedule_tick(ev, mi->q, 0, mi->time); status = _read_byte(mi); if (status < 0) return EEVENT; switch (status & 0xF0) { case 0x80: ev->type = SND_SEQ_EVENT_NOTEOFF; ev->data.note.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.note = data & 0x7F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.velocity = data & 0x7F; break; case 0x90: ev->type = SND_SEQ_EVENT_NOTEON; ev->data.note.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.note = data & 0x7F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.velocity = data & 0x7F; break; case 0xA0: ev->type = SND_SEQ_EVENT_KEYPRESS; ev->data.note.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.note = data & 0x7F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.note.velocity = data & 0x7F; break; case 0xB0: ev->type = SND_SEQ_EVENT_CONTROLLER; ev->data.control.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.control.param = data & 0x7F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.control.value = data & 0x7F; break; case 0xC0: ev->type = SND_SEQ_EVENT_PGMCHANGE; ev->data.control.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.control.value = data & 0x7F; break; case 0xD0: ev->type = SND_SEQ_EVENT_CHANPRESS; ev->data.control.channel = status & 0x0F; data = _read_byte(mi); if (data < 0 ) return EEVENT; ev->data.control.value = data & 0x7F; break; case 0xE0: ev->type = SND_SEQ_EVENT_PITCHBEND; ev->data.control.channel = status & 0x0F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.control.param = data & 0x7F; data = _read_byte(mi); if (data < 0) return EEVENT; ev->data.control.value = data & 0x7F; break; case 0xF0: // these events are special // we should not send only the tempo changes // and sysex events switch (status & 0xFF) { case 0xF0: ev->type = SND_SEQ_EVENT_SYSEX; length = _read_var_value(mi); if (length < 1) return EEVENT; if (_data_left(mi) < length) return EEVENT; ev->data.ext.len = length; buf = (void *)malloc(length); if (buf == NULL) return EMALLOC; memcpy(buf, &mi->data[mi->pos], length); snd_seq_ev_set_variable(ev, length, buf); mi->pos += length; break; case 0xFF: data = _read_byte(mi); if (data < 0) return EEVENT; if (data == 0x51) { length = _read_var_value(mi); if (length != 3) return EEVENT; if (_data_left(mi) < length) return EEVENT; ev->type = SND_SEQ_EVENT_TEMPO; ev->data.queue.queue = mi->q; ev->data.queue.param.value = (mi->data[mi->pos] << 16) | (mi->data[mi->pos+1] << 8) | (mi->data[mi->pos+2]); mi->pos += length; } else { snd_seq_ev_clear(ev); // skip this event length = _read_var_value(mi); if (length < 0) return EEVENT; if (_data_left(mi) < length) return EEVENT; mi->pos += length; } break; default: return EEVENT; } break; default: return EEVENT; } return 0; }