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];
 | 
						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)
 | 
						if (mf->p < mf->data + mf->size)
 | 
				
			||||||
		return mf->size + mf->data - mf->p;
 | 
							return mf->size + mf->data - mf->p;
 | 
				
			||||||
	return 0;
 | 
						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)
 | 
					static int read_mthd(struct midi_file *mf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (avail(mf) < 14)
 | 
						if (mf_avail(mf) < 14 ||
 | 
				
			||||||
		return -EIO;
 | 
						    memcmp(mf->p, "MThd", 4) != 0)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (memcmp(mf->p, "MThd", 4))
 | 
					 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mf->length = parse_be32(mf->p + 4);
 | 
						mf->length = parse_be32(mf->p + 4);
 | 
				
			||||||
	mf->format = parse_be16(mf->p + 8);
 | 
						mf->format = parse_be16(mf->p + 8);
 | 
				
			||||||
	mf->ntracks = parse_be16(mf->p + 10);
 | 
						mf->ntracks = parse_be16(mf->p + 10);
 | 
				
			||||||
	mf->division = parse_be16(mf->p + 12);
 | 
						mf->division = parse_be16(mf->p + 12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mf->p += 14;
 | 
						mf->p += 14;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -67,9 +76,8 @@ int midi_file_init(struct midi_file *mf, const char *mode,
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(*mf);
 | 
						spa_zero(*mf);
 | 
				
			||||||
	mf->data = data;
 | 
						mf->data = mf->p = data;
 | 
				
			||||||
	mf->size = size;
 | 
						mf->size = size;
 | 
				
			||||||
	mf->p = data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = read_mthd(mf)) < 0)
 | 
						if ((res = read_mthd(mf)) < 0)
 | 
				
			||||||
		return res;
 | 
							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)
 | 
					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;
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (memcmp(mf->p, "MTrk", 4))
 | 
						track->data = track->p = mf->p + 8;
 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	track->p = track->data = mf->p + 8;
 | 
					 | 
				
			||||||
	track->size = parse_be32(mf->p + 4);
 | 
						track->size = parse_be32(mf->p + 4);
 | 
				
			||||||
	mf->p += track->size + 8;
 | 
					
 | 
				
			||||||
 | 
						mf->p = track->data + track->size;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int parse_varlen(struct midi_file *mf, struct midi_track *tr, uint32_t *result)
 | 
					static int parse_varlen(struct midi_file *mf, struct midi_track *tr, uint32_t *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i, value = 0;
 | 
						uint32_t value = 0;
 | 
				
			||||||
	uint8_t b;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	value = 0;
 | 
						while (tr_avail(tr) > 0) {
 | 
				
			||||||
	for (i = 0; i < 4; i++) {
 | 
							uint8_t b = *tr->p++;
 | 
				
			||||||
		if (tr->p >= tr->data + tr->size) {
 | 
					 | 
				
			||||||
			tr->eof = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b = *tr->p++;
 | 
					 | 
				
			||||||
		value = (value << 7) | (b & 0x7f);
 | 
							value = (value << 7) | (b & 0x7f);
 | 
				
			||||||
		if ((b & 0x80) == 0)
 | 
							if ((b & 0x80) == 0)
 | 
				
			||||||
			break;
 | 
								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)
 | 
					static int peek_event(struct midi_file *mf, struct midi_track *tr, struct midi_event *event)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t *save, status;
 | 
						uint8_t *save, status;
 | 
				
			||||||
	uint32_t size = 0;
 | 
						uint32_t size;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tr->eof || tr->p >= tr->data + tr->size)
 | 
						if (tr_avail(tr) == 0)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	save = tr->p;
 | 
						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) {
 | 
						if ((status & 0x80) == 0) {
 | 
				
			||||||
		status = tr->running_status;
 | 
							status = tr->running_status;
 | 
				
			||||||
		event->data = tr->p;
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		tr->running_status = status;
 | 
							tr->running_status = status;
 | 
				
			||||||
		event->data = ++tr->p;
 | 
							tr->p++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	event->status = status;
 | 
						event->status = status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status < 0xf0) {
 | 
						switch (status) {
 | 
				
			||||||
		size++;
 | 
						case 0xc0 ... 0xdf:
 | 
				
			||||||
		if (status < 0xc0 || status >= 0xe0)
 | 
							size = 1;
 | 
				
			||||||
			size++;
 | 
							break;
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (status == 0xff) {
 | 
					 | 
				
			||||||
			event->meta = *tr->p++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if ((res = parse_varlen(mf, tr, &size)) < 0)
 | 
						case 0x00 ... 0xbf:
 | 
				
			||||||
				return res;
 | 
						case 0xe0 ... 0xef:
 | 
				
			||||||
 | 
							size = 2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			event->data = tr->p;
 | 
						case 0xff:
 | 
				
			||||||
 | 
							event->meta = *tr->p++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			switch (event->meta) {
 | 
							if ((res = parse_varlen(mf, tr, &size)) < 0)
 | 
				
			||||||
			case 0x2f:
 | 
								return res;
 | 
				
			||||||
				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;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else if (status == 0xf0 || status == 0xf7) {
 | 
							switch (event->meta) {
 | 
				
			||||||
			if ((res = parse_varlen(mf, tr, &size)) < 0)
 | 
							case 0x2f:
 | 
				
			||||||
				return res;
 | 
								tr->eof = true;
 | 
				
			||||||
			event->data = tr->p;
 | 
								break;
 | 
				
			||||||
		} else {
 | 
							case 0x51:
 | 
				
			||||||
			return -EIO;
 | 
								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;
 | 
						tr->p = save;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	event->size = size;
 | 
						event->size = size;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,7 +197,6 @@ int midi_file_add_track(struct midi_file *mf, struct midi_track *track)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	track->tick = delta_time;
 | 
						track->tick = delta_time;
 | 
				
			||||||
	spa_list_init(&track->events);
 | 
					 | 
				
			||||||
	spa_list_append(&mf->tracks, &track->link);
 | 
						spa_list_append(&mf->tracks, &track->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						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;
 | 
						struct midi_track *tr, *found = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_for_each(tr, &mf->tracks, link) {
 | 
						spa_list_for_each(tr, &mf->tracks, link) {
 | 
				
			||||||
		if (tr->eof)
 | 
							if (tr_avail(tr) == 0)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (found == NULL || tr->tick < found->tick)
 | 
							if (found == NULL || tr->tick < found->tick)
 | 
				
			||||||
			found = tr;
 | 
								found = tr;
 | 
				
			||||||
| 
						 | 
					@ -222,15 +225,10 @@ int midi_file_consume_event(struct midi_file *mf, struct midi_event *event)
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tr->p = event->data + event->size;
 | 
						tr->p = event->data + event->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = parse_varlen(mf, tr, &delta_time)) < 0)
 | 
						if ((res = parse_varlen(mf, tr, &delta_time)) < 0)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tr->tick += delta_time;
 | 
						tr->tick += delta_time;
 | 
				
			||||||
	return 0;
 | 
						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;
 | 
						int64_t tick;
 | 
				
			||||||
	uint8_t running_status;
 | 
						uint8_t running_status;
 | 
				
			||||||
	unsigned int eof:1;
 | 
						unsigned int eof:1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct spa_list events;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct midi_file {
 | 
					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_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_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