mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-03-26 07:57:57 -04:00
rawmidi: hide the frame structure using a decoder function
The frame structure should be hidden. Remove it and add snd_rawmidi_decode_frame0() which returns the timestamp and the midi chunk pointer to the application. BugLink: https://github.com/alsa-project/alsa-lib/issues/172 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
754c696aef
commit
5e8a5fb754
3 changed files with 58 additions and 36 deletions
|
|
@ -93,26 +93,6 @@ typedef enum _snd_rawmidi_framing {
|
|||
SND_RAWMIDI_FRAMING_TSTAMP = 1,
|
||||
} snd_rawmidi_framing_t;
|
||||
|
||||
#define SND_RAWMIDI_FRAME_TYPE_DEFAULT 0
|
||||
|
||||
#define SND_RAWMIDI_FRAMING_DATA_LENGTH 16
|
||||
|
||||
/** Incoming RawMidi bytes is put inside this container if tstamp type framing is enabled. */
|
||||
struct _snd_rawmidi_framing_tstamp {
|
||||
/**
|
||||
* For now, frame_type is always SND_RAWMIDI_FRAME_TYPE_DEFAULT.
|
||||
* Midi 2.0 is expected to add new types here.
|
||||
* Applications are expected to skip unknown frame types.
|
||||
*/
|
||||
uint8_t frame_type;
|
||||
uint8_t length; /* number of valid bytes in data field */
|
||||
uint8_t reserved[2];
|
||||
uint32_t tv_nsec; /* nanoseconds */
|
||||
uint64_t tv_sec; /* seconds */
|
||||
uint8_t data[SND_RAWMIDI_FRAMING_DATA_LENGTH];
|
||||
} __attribute__((packed));
|
||||
typedef struct _snd_rawmidi_framing_tstamp snd_rawmidi_framing_tstamp_t;
|
||||
|
||||
int snd_rawmidi_open(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
|
||||
const char *name, int mode);
|
||||
int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
|
||||
|
|
@ -184,6 +164,8 @@ int snd_rawmidi_drain(snd_rawmidi_t *rmidi);
|
|||
int snd_rawmidi_drop(snd_rawmidi_t *rmidi);
|
||||
ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size);
|
||||
ssize_t snd_rawmidi_read(snd_rawmidi_t *rmidi, void *buffer, size_t size);
|
||||
ssize_t snd_rawmidi_decode_frame0(snd_rawmidi_t *rmidi, void *buffer, size_t size,
|
||||
struct timespec *tstamp, void *data, size_t *data_size);
|
||||
const char *snd_rawmidi_name(snd_rawmidi_t *rmidi);
|
||||
snd_rawmidi_type_t snd_rawmidi_type(snd_rawmidi_t *rmidi);
|
||||
snd_rawmidi_stream_t snd_rawmidi_stream(snd_rawmidi_t *rawmidi);
|
||||
|
|
|
|||
|
|
@ -1075,6 +1075,41 @@ ssize_t snd_rawmidi_read(snd_rawmidi_t *rawmidi, void *buffer, size_t size)
|
|||
{
|
||||
assert(rawmidi);
|
||||
assert(rawmidi->stream == SND_RAWMIDI_STREAM_INPUT);
|
||||
if ((rawmidi->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK) == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
|
||||
size &= ~(sizeof(struct snd_rawmidi_framing_tstamp) - 1);
|
||||
assert(buffer || size == 0);
|
||||
return (rawmidi->ops->read)(rawmidi, buffer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief decode the MIDI frame with timestamp
|
||||
* \param rawmidi RawMidi handle
|
||||
* \param buffer frame buffer with the frame stream
|
||||
* \param size frame buffer size in bytes
|
||||
* \param tstamp returned timestamp
|
||||
* \param data returned pointer to the midi data
|
||||
* \param data_size returned size of the midi data
|
||||
* \return number of consumed bytes otherwise a negative error code
|
||||
*/
|
||||
ssize_t snd_rawmidi_decode_frame0(snd_rawmidi_t *rawmidi, void *buffer, size_t size,
|
||||
struct timespec *tstamp, void *data, size_t *data_size)
|
||||
{
|
||||
struct snd_rawmidi_framing_tstamp *f;
|
||||
|
||||
assert(rawmidi && buffer && tstamp && data && data_size);
|
||||
assert(rawmidi->stream == SND_RAWMIDI_STREAM_INPUT);
|
||||
if (size < sizeof(*data))
|
||||
return 0;
|
||||
if ((rawmidi->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK) != SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
|
||||
return -EINVAL;
|
||||
f = buffer;
|
||||
if (f->frame_type != 0)
|
||||
return -EINVAL;
|
||||
if (f->length == 0 || f->length > SNDRV_RAWMIDI_FRAMING_DATA_LENGTH)
|
||||
return -EINVAL;
|
||||
tstamp->tv_sec = f->tv_sec;
|
||||
tstamp->tv_nsec = f->tv_nsec;
|
||||
*(void **)data = f->data;
|
||||
*data_size = f->length;
|
||||
return sizeof(*f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,27 +179,32 @@ int main(int argc,char** argv)
|
|||
}
|
||||
|
||||
if (handle_in) {
|
||||
unsigned char ch;
|
||||
snd_rawmidi_framing_tstamp_t frame;
|
||||
ssize_t ret, ret2;
|
||||
unsigned char buf[1024];
|
||||
while (!stop) {
|
||||
if (clock_type != -1) {
|
||||
snd_rawmidi_read(handle_in, &frame, sizeof(frame));
|
||||
if (verbose) {
|
||||
int i;
|
||||
if (frame.frame_type) {
|
||||
fprintf(stderr, "read unknown frame %d", frame.frame_type);
|
||||
continue;
|
||||
ret = snd_rawmidi_read(handle_in, &buf, sizeof(buf));
|
||||
if (clock_type != -1 && ret > 0) {
|
||||
unsigned char *ptr = buf;
|
||||
while (ret > 0) {
|
||||
struct timespec tstamp;
|
||||
unsigned char *data;
|
||||
size_t j, data_size;
|
||||
ret2 = snd_rawmidi_decode_frame0(handle_in, ptr, ret, &tstamp, &data, &data_size);
|
||||
if (ret2 <= 0) {
|
||||
fprintf(stderr, "read unknown frame %zd\n", ret2);
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "read [%lld:%09d]", frame.tv_sec, frame.tv_nsec);
|
||||
for (i = 0; i < frame.length; i++)
|
||||
fprintf(stderr, " %02x", frame.data[i]);
|
||||
ptr += ret2;
|
||||
ret -= ret2;
|
||||
fprintf(stderr, "read [%lld:%09lld]", (long long)tstamp.tv_sec, (long long)tstamp.tv_nsec);
|
||||
for (j = 0; j < data_size; j++)
|
||||
fprintf(stderr, " %02x", data[j]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
snd_rawmidi_read(handle_in,&ch,1);
|
||||
} else {
|
||||
if (verbose)
|
||||
fprintf(stderr,"read %02x\n",ch);
|
||||
for (i = 0; i < ret; i++)
|
||||
fprintf(stderr,"read %02x\n",buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue