control: improve UMP to Midi conversiom

Improve the spa_ump_to_midi function so that it can consume multiple UMP
messages and produce multiple midi messages.

Some UMP messages (like program changes) need to be translated into up
to 3 midi messages. Do this byt adding a state to the function and by
making it consume the input bytes, just like the spa_ump_from_midi
function.

Adapt code to this new world. This is a little API break..
This commit is contained in:
Wim Taymans 2025-08-19 17:41:03 +02:00
parent bf10458604
commit e35a8554f8
13 changed files with 307 additions and 228 deletions

View file

@ -496,41 +496,46 @@ int midi_file_write_event(struct midi_file *mf, const struct midi_event *event)
{
struct midi_track *tr;
uint32_t tick;
void *data;
void *data, *ev_data;
size_t size;
int res;
int res, ev_size;
uint8_t ev[32];
uint64_t state = 0;
spa_return_val_if_fail(event != NULL, -EINVAL);
spa_return_val_if_fail(mf != NULL, -EINVAL);
spa_return_val_if_fail(event->track == 0, -EINVAL);
spa_return_val_if_fail(event->size > 1, -EINVAL);
switch (event->type) {
case MIDI_EVENT_TYPE_MIDI1:
data = event->data;
size = event->size;
break;
case MIDI_EVENT_TYPE_UMP:
data = ev;
size = spa_ump_to_midi((uint32_t*)event->data, event->size, ev, sizeof(ev));
if (size == 0)
return 0;
break;
default:
return -EINVAL;
}
data = event->data;
size = event->size;
tr = &mf->tracks[event->track];
tick = (uint32_t)(event->sec * (1000000.0 * mf->info.division) / (double)mf->tempo);
CHECK_RES(write_varlen(mf, tr, tick - tr->tick));
tr->tick = tick;
while (size > 0) {
switch (event->type) {
case MIDI_EVENT_TYPE_MIDI1:
ev_data = data;
ev_size = size;
size = 0;
break;
case MIDI_EVENT_TYPE_UMP:
ev_size = spa_ump_to_midi((const uint32_t**)&data, &size, ev, sizeof(ev), &state);
if (ev_size <= 0)
return ev_size;
ev_data = ev;
break;
default:
return -EINVAL;
}
CHECK_RES(write_n(mf->file, data, size));
tr->size += size;
CHECK_RES(write_varlen(mf, tr, tick - tr->tick));
tr->tick = tick;
CHECK_RES(write_n(mf->file, ev_data, ev_size));
tr->size += ev_size;
}
return 0;
}