diff --git a/src/tools/midifile.c b/src/tools/midifile.c index 30457c515..feff133c7 100644 --- a/src/tools/midifile.c +++ b/src/tools/midifile.c @@ -140,7 +140,7 @@ static int peek_event(struct midi_file *mf, struct midi_track *tr, struct midi_e return res < 0 ? res : -EIO; event->track = tr; - event->tick = tr->tick; + event->sec = mf->tick_sec + ((tr->tick - mf->tick_start) * (double)mf->tempo) / (1000000.0 * mf->division); start = event->offset = tr->offset; status = buffer[0]; @@ -183,6 +183,8 @@ static int peek_event(struct midi_file *mf, struct midi_track *tr, struct midi_e if ((res = mf->events->read(mf->data, tr->start + tr->offset, buffer, 3)) != 3) return res < 0 ? res : -EIO; + mf->tick_sec = event->sec; + mf->tick_start = tr->tick; mf->tempo = (buffer[0]<<16) | (buffer[1]<<8) | buffer[2]; break; } diff --git a/src/tools/midifile.h b/src/tools/midifile.h index 8c600383e..782332507 100644 --- a/src/tools/midifile.h +++ b/src/tools/midifile.h @@ -32,7 +32,7 @@ struct midi_event { struct midi_track *track; - int64_t tick; + double sec; uint8_t status; uint8_t meta; uint32_t offset; @@ -69,6 +69,8 @@ struct midi_file { uint32_t offset; int64_t tick; + double tick_sec; + double tick_start; const struct midi_events *events; void *data; diff --git a/src/tools/pw-cat.c b/src/tools/pw-cat.c index ae361bdf5..46107d887 100644 --- a/src/tools/pw-cat.c +++ b/src/tools/pw-cat.c @@ -989,8 +989,10 @@ static int midi_play(struct data *d, void *src, unsigned int n_frames) if (res < 0) return res; - frame = ev.tick * ((double)d->position->clock.rate.denom * d->md.file.tempo) / - (1000000.0 * d->md.file.division); + if (ev.status == 0xff) + goto next; + + frame = ev.sec * d->position->clock.rate.denom; if (frame < first_frame) frame = 0; @@ -1001,11 +1003,10 @@ static int midi_play(struct data *d, void *src, unsigned int n_frames) spa_pod_builder_control(&b, frame, SPA_CONTROL_Midi); buf[0] = ev.status; - if (ev.status == 0xff) - buf[1] = ev.meta; - midi_read(d, ev.offset, ev.status == 0xff ? &buf[2] : &buf[1], ev.size); + midi_read(d, ev.offset, &buf[1], ev.size); spa_pod_builder_bytes(&b, buf, ev.size + 1); +next: midi_file_consume_event(&d->md.file, &ev); } spa_pod_builder_pop(&b, &f);