From cc1ed84f9f0d42bc1b14a06fafdf30bb62ba31c0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 19 Feb 2020 10:48:16 +0100 Subject: [PATCH] midi: simplify some things --- src/tools/midifile.c | 126 +++++++++++++++++++++---------------------- src/tools/midifile.h | 6 --- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/src/tools/midifile.c b/src/tools/midifile.c index 0975a120d..ed6c510fd 100644 --- a/src/tools/midifile.c +++ b/src/tools/midifile.c @@ -38,25 +38,34 @@ static inline uint32_t parse_be32(const uint8_t *in) return (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3]; } -static inline int avail(struct midi_file *mf) +static inline int mf_avail(struct midi_file *mf) { if (mf->p < mf->data + mf->size) return mf->size + mf->data - mf->p; return 0; } +static inline int tr_avail(struct midi_track *tr) +{ + if (tr->eof) + return 0; + if (tr->p < tr->data + tr->size) + return tr->size + tr->data - tr->p; + tr->eof = true; + return 0; +} + static int read_mthd(struct midi_file *mf) { - if (avail(mf) < 14) - return -EIO; - - if (memcmp(mf->p, "MThd", 4)) + if (mf_avail(mf) < 14 || + memcmp(mf->p, "MThd", 4) != 0) return -EIO; mf->length = parse_be32(mf->p + 4); mf->format = parse_be16(mf->p + 8); mf->ntracks = parse_be16(mf->p + 10); mf->division = parse_be16(mf->p + 12); + mf->p += 14; return 0; } @@ -67,9 +76,8 @@ int midi_file_init(struct midi_file *mf, const char *mode, int res; spa_zero(*mf); - mf->data = data; + mf->data = mf->p = data; mf->size = size; - mf->p = data; if ((res = read_mthd(mf)) < 0) return res; @@ -84,30 +92,23 @@ int midi_file_init(struct midi_file *mf, const char *mode, static int read_mtrk(struct midi_file *mf, struct midi_track *track) { - if (avail(mf) < 8) + if (mf_avail(mf) < 8 || + memcmp(mf->p, "MTrk", 4) != 0) return -EIO; - if (memcmp(mf->p, "MTrk", 4)) - return -EIO; - - track->p = track->data = mf->p + 8; + track->data = track->p = mf->p + 8; track->size = parse_be32(mf->p + 4); - mf->p += track->size + 8; + + mf->p = track->data + track->size; return 0; } static int parse_varlen(struct midi_file *mf, struct midi_track *tr, uint32_t *result) { - uint32_t i, value = 0; - uint8_t b; + uint32_t value = 0; - value = 0; - for (i = 0; i < 4; i++) { - if (tr->p >= tr->data + tr->size) { - tr->eof = true; - break; - } - b = *tr->p++; + while (tr_avail(tr) > 0) { + uint8_t b = *tr->p++; value = (value << 7) | (b & 0x7f); if ((b & 0x80) == 0) break; @@ -119,10 +120,10 @@ static int parse_varlen(struct midi_file *mf, struct midi_track *tr, uint32_t *r static int peek_event(struct midi_file *mf, struct midi_track *tr, struct midi_event *event) { uint8_t *save, status; - uint32_t size = 0; + uint32_t size; int res; - if (tr->eof || tr->p >= tr->data + tr->size) + if (tr_avail(tr) == 0) return -EIO; save = tr->p; @@ -133,51 +134,54 @@ static int peek_event(struct midi_file *mf, struct midi_track *tr, struct midi_e if ((status & 0x80) == 0) { status = tr->running_status; - event->data = tr->p; } else { tr->running_status = status; - event->data = ++tr->p; + tr->p++; } event->status = status; - if (status < 0xf0) { - size++; - if (status < 0xc0 || status >= 0xe0) - size++; - } else { - if (status == 0xff) { - event->meta = *tr->p++; + switch (status) { + case 0xc0 ... 0xdf: + size = 1; + break; - if ((res = parse_varlen(mf, tr, &size)) < 0) - return res; + case 0x00 ... 0xbf: + case 0xe0 ... 0xef: + size = 2; + break; - event->data = tr->p; + case 0xff: + event->meta = *tr->p++; - switch (event->meta) { - case 0x2f: - tr->eof = true; - break; - case 0x51: - if (size < 3) - break; - mf->tick_sec = event->sec; - mf->tick_start = tr->tick; - mf->tempo = (tr->p[0]<<16) | (tr->p[1]<<8) | tr->p[2]; - break; - } + if ((res = parse_varlen(mf, tr, &size)) < 0) + return res; - } else if (status == 0xf0 || status == 0xf7) { - if ((res = parse_varlen(mf, tr, &size)) < 0) - return res; - event->data = tr->p; - } else { - return -EIO; + switch (event->meta) { + case 0x2f: + tr->eof = true; + break; + case 0x51: + if (size < 3) + return -EIO; + mf->tick_sec = event->sec; + mf->tick_start = tr->tick; + mf->tempo = (tr->p[0]<<16) | (tr->p[1]<<8) | tr->p[2]; + break; } + break; + + case 0xf0: + case 0xf7: + if ((res = parse_varlen(mf, tr, &size)) < 0) + return res; + break; + default: + return -EIO; } + event->data = tr->p; tr->p = save; event->size = size; - return 0; } @@ -193,7 +197,6 @@ int midi_file_add_track(struct midi_file *mf, struct midi_track *track) return res; track->tick = delta_time; - spa_list_init(&track->events); spa_list_append(&mf->tracks, &track->link); return 0; @@ -204,7 +207,7 @@ int midi_file_peek_event(struct midi_file *mf, struct midi_event *event) struct midi_track *tr, *found = NULL; spa_list_for_each(tr, &mf->tracks, link) { - if (tr->eof) + if (tr_avail(tr) == 0) continue; if (found == NULL || tr->tick < found->tick) found = tr; @@ -222,15 +225,10 @@ int midi_file_consume_event(struct midi_file *mf, struct midi_event *event) int res; tr->p = event->data + event->size; + if ((res = parse_varlen(mf, tr, &delta_time)) < 0) return res; + tr->tick += delta_time; return 0; } - -int midi_file_add_event(struct midi_file *mf, struct midi_track *track, struct midi_event *event) -{ - spa_list_append(&track->events, &event->link); - return 0; -} - diff --git a/src/tools/midifile.h b/src/tools/midifile.h index a04458e17..6667b861f 100644 --- a/src/tools/midifile.h +++ b/src/tools/midifile.h @@ -50,8 +50,6 @@ struct midi_track { int64_t tick; uint8_t running_status; unsigned int eof:1; - - struct spa_list events; }; struct midi_file { @@ -79,7 +77,3 @@ int midi_file_add_track(struct midi_file *mf, struct midi_track *track); int midi_file_peek_event(struct midi_file *mf, struct midi_event *event); int midi_file_consume_event(struct midi_file *mf, struct midi_event *event); - -int midi_file_add_event(struct midi_file *mf, struct midi_track *track, struct midi_event *event); - -