[vorbis-dev] Ogg MIDI proposal

Ralph Giles
Sat, 25 Aug 2001 18:24:43 -0000

On Saturday, August 25, 2001, at 07:34 , Jack Moffitt wrote:

A file with Vorbis and Midi will look like:

<Vorbis header pages><MIDI header page><Vorbis data
page><MIDI data page>...

that should be <vorbis header page><MIDI header page>...etc.

According to the ogg specification, all the header pages (marked by the bos
flag) must occur together, before the first non-header page of any of the
logical bitstreams.

MIDI pages will be placed in sync with vorbis pages (immediately following
their corresponding Vorbis page).  Since MIDIs are tiny, it is likely
there will be very few pages of MIDI data.

Immediately following the vorbis page corresponding to the start or the end of
the midi data? I'd suggest the start, since the midi data will be cheaper to
buffer. :)

You also don't mention how the granule_pos field of the ogg page will be set
(called 'pcm absolute position' in framing.html). I propose it contain
the accumulated tick number in the timebase units the midi data uses. That means
the multiplexer has to read the timebase header of the midi stream *and* keep
track of the current tempo to maintain sync. Maybe we should instead specify
(only) that the midi data must come *before* the corresponding vorbis data. That
way the decoder needn't worry about midi underflow, and a dumb encoder can
just stick the whole midi stream at the beginning. The head ordering requirement
will remain in place, and the page flush requirement will ensure this
arrangement is possible.

Each MIDI Ogg packet will contain rougly 512 bytes aligned to MIDI event
boundaries.  This means approximately 8 MIDI packets will normally be place
in an Ogg page.

I picked 512 out of the air, and would be happy to hear any arguments for
different numbers.

The MIDI header will be:

'OggMIDI\000'
version (1 byte) - this is the OggMIDI version supported, starts from 0

Is the \000 part of the magic string, or the value of the version byte?

time format (1 byte) - this is the time format, 1 for ticks per
        quarternote; 24,25,29,30 for SMTPE time

0 is a better flag for 'per quarternote'.

timebase (2 bytes) - subdivisions per SMTPE frame or ticks per quarternote

This field is written little-endian, like the rest of ogg. The midi format
itself is big endian. We won't muck with the ordering within the event
stream (data packets) itself.

MIDI packet format
------------------
<midi event><midi event>...

Note that the midi data packets are sections of the raw event bytestream chopped
at an event boundary, and have no OggMIDI-specific header. You  just concatenate
them to get the midi track back again. We rely on ogg for all framing and sync.
I proposed that the packet boundaries should also occur before a non-zero
timestamp.

We also talked about expanding the context of all midi events to simplify random
access. (MIDI lets you omit the event status byte when you're only updating
a parameter on the 'current' note.) Do we want to drop that since there
are other issues with starting midi playback mid-stream?

Comments, suggestions?

Guess you should have let me review :)

 -r