Alternate format for OggPCM
The following is an alternate format for OggPCM. This is a work in progress and not a final proposal.
Note that unless otherwise noted, all multi-byte fields use the network byte order (big endian). The first packed in a stream MUST be the main header packet. The second packet MUST be the comment packet. Some extra header packets MAY be included after the comment header, provided this is identified in the main header. The packets that follow MUST all be data packets.
Main Header Packet
Multibyte fields in the header packets are packed in big endian order, to be consistent with network byte order. A header packet contains the following fields:
32 "PCM " Codec identifier 16 0x00 Version Major (breaks backwards compatability to increment) 16 0x00 Version Minor (backwards compatable, ie, more supported format id's) 32 [uint] PCM format 32 [uint] Significant bits 32 [uint] Sampling rate 32 [uint] Number of Channels (< 256) 16 [uint] Maximum number of frames per packet 16 [uint] Number of extra headers
The "Maximum number of frames per packet" field is meant to notify an application reading the file that no data packet will contain more than a certain number of frames. This not only makes implementation easier, but also provides information on how much needs to be buffered when streaming PCM files. A value of 0 means a maximum of 65536 frames. Implementations SHOULD make this field such that packets do not get split into multiple pages.
The "significant bits" field specifies how many bits are actually used. The other bits MUST be zero. This can be used to support audio with any resolution. For example, 12-bit PCM can be supported as "16 bit PCM" for the format and 12 for the number of significant bits.
A "vorbis comment" packet follows the header and the optional extra headers, if any. The format used is the same as for Vorbis with the exception that there is no packet identifier (so the packet is exactly like it is for Speex).
Extra Headers (optional)
Extra headers contain additional information about the OggPCM stream. Each extra header is defined as:
32 [uint] Header ID ... Header data
Channel Mapping Header
The channel mapping header is defined as:
32 0x00000000 Header ID 16 [uint] Major version 16 [uint] Minor version 32 [uint] Channel type 32xN [uint] Channel map (one for each channel)
As an example, stereo might be encoded as:
channel_type = OGG_CHANNEL_MAP_STEREO channel_map  = OGG_CHANNEL_STEREO_LEFT channel_map  = OGG_CHANNEL_STEREO_RIGHT
channel_type = OGG_CHANNEL_MAP_STEREO channel_map  = OGG_CHANNEL_STEREO_RIGHT channel_map  = OGG_CHANNEL_STEREO_LEFT
All channel_types less than 0x80000000 are reserved for use by Xiph and all the ones above are allowed for application specific extensions.
Channel Conversion Header
Any number of channel conversion headers can be specified. This header specifies how to down-mix the data to a another format.
32 0x00000001 Remixing Header Id 16 [uint] Major version 16 [uint] Minor version 32 [uint] Target Channel type 32xMxN [sint] Target Channel (M) x Src Channel (N) Gain array
The ordering of the mixing matrix is such that source channel gains are consecutive. The gain (note: *signed* integer) has the 16 MSBs for the integer part (including sign) and 16 bits for the fracional part of the gain. Note: the gain can be negative.
Data packets contain the raw PCM audio in interleaved format (complete frames are encoded sequentially) with the following definitions/restrictions:
- A PCM "frame" is composed of samples for all channels at a given time.
- Any OggPCM packet should only contain complete frames (ie samples for all channels at a given sampling instance). Partial frames are forbidden.
- There is no padding allowed in a frame except when some bits (<8) are needed to complete a byte. This means that packet size has a direct relationship to the number of frames in the packet (for purposes of seeking).
Supported PCM Formats
Format ID Short Name Description -- Integer coding 0x00000000 OGGPCM_FMT_S8 Signed integer 8 bit 0x00000001 OGGPCM_FMT_U8 Unsigned integer 8 bit 0x00000002 OGGPCM_FMT_S16_LE Signed integer 16 bit little endian 0x00000003 OGGPCM_FMT_S16_BE Signed integer 16 bit big endian 0x00000004 OGGPCM_FMT_S24_LE Signed integer 24 bit little endian 0x00000005 OGGPCM_FMT_S24_BE Signed integer 24 bit big endian 0x00000006 OGGPCM_FMT_S32_LE Signed integer 32 bit little endian 0x00000007 OGGPCM_FMT_S32_BE Signed integer 32 bit big endian -- -- Compressed PCM 0x00000008 OGGPCM_FMT_ULAW G.711 u-law encoding (8 bit) 0x00000009 OGGPCM_FMT_ALAW G.711 A-law encoding (8 bit) 0x0000000A OGGPCM_FMT_ULAW12 Wideband u-law encoding (12 bit) 0x0000000B OGGPCM_FMT_ALAW12 Wideband A-law encoding (12 bit) -- -- IEEE Floating point coding 0x00000010 OGGPCM_FMT_FLT32_LE IEEE Float (-1,1) 32 bit little endian 0x00000011 OGGPCM_FMT_FLT32_BE IEEE Float (-1,1) 32 bit big endian 0x00000012 OGGPCM_FMT_FLT64_LE IEEE Float (-1,1) 64 bit little endian 0x00000013 OGGPCM_FMT_FLT64_BE IEEE Float (-1,1) 64 bit big endian 0x00000014 OGGPCM_FMT_FLT32B_LE IEEE Float (-32768,32768) 32 bit little endian 0x00000015 OGGPCM_FMT_FLT32B_BE IEEE Float (-32768,32768) 32 bit big endian 0x00000016 OGGPCM_FMT_FLT64B_LE IEEE Float (-32768,32768) 64 bit little endian 0x00000017 OGGPCM_FMT_FLT64B_BE IEEE Float (-32768,32768) 64 bit big endian