mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
midi: simplify some things
This commit is contained in:
parent
7df66cd6ad
commit
cc1ed84f9f
2 changed files with 62 additions and 70 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue