mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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