423 lines
16 KiB
HTML
423 lines
16 KiB
HTML
<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
|
|
<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
|
|
<nobr><img src="white-ogg.png"><img src="vorbisword2.png"></nobr><p>
|
|
|
|
<h1><font color=#000070>
|
|
Ogg Vorbis I format specification: residue setup and decode
|
|
</font></h1>
|
|
|
|
<em>Last update to this document: July 19, 2002</em><br>
|
|
|
|
<h1>Overview</h1>
|
|
|
|
A residue vector represents the fine detail of the audio spectrum of
|
|
one channel in an audio frame after the encoder subtracts the floor
|
|
curve and performs any channel coupling. A residue vector may
|
|
represent spectral lines, spectral magnitude, spectral phase or
|
|
hybrids as mixed by channel coupling. The exact semantic content of
|
|
the vector does not matter to the residue abstraction.<p>
|
|
|
|
Whatever the exact qualities, the Vorbis residue abstraction codes the
|
|
residue vectors into the bitstream packet, and then reconstructs the
|
|
vectors during decode. Vorbis makes use of three different encoding
|
|
variants (numbered 0, 1 and 2) of the same basic vector encoding
|
|
abstraction.<p>
|
|
|
|
<h1>Residue format</h1>
|
|
|
|
Reside format partitions each vector in the vector bundle into chunks,
|
|
classifies each chunk, encodes the chunk classifications and finally
|
|
encodes the chunks themselves using the the specific VQ arrangement
|
|
defined for each selected selected classification. The exact
|
|
interleaving and partitioning vary by residue encoding number, however
|
|
the high-level process used to classify and encode the residue vector
|
|
is the same in all three variants.<p>
|
|
|
|
A set of coded residue vectors are all of the same length. High level
|
|
coding structure, ignoring for the moment exactly how a partition is
|
|
encoded and simply trusting that it is, is as follows:<p>
|
|
|
|
<ul>
|
|
<li>Each vector is partitioned into multiple equal sized chunks
|
|
according to configuration specified. If we have a vector size of
|
|
<i>n</i>, a partition size <i>residue_partition_size</i>, and a total
|
|
of <i>ch</i> residue vectors, the total number of partitioned chunks
|
|
coded is <i>n</i>/<i>residue_partition_size</i>*<i>ch</i>. It is
|
|
important to note that the integer division truncates. In the below
|
|
example, we assume an example <i>residue_partition_size</i> of 8.<p>
|
|
|
|
<li>Each partition in each vector has a classification number that
|
|
specifies which of multiple configured VQ codebook setups are used to
|
|
decode that partition. The classification numbers of each partition
|
|
can be thought of as forming a vector in their own right, as in the
|
|
illustration below. Just as the residue vectors are coded in grouped
|
|
partitions to increase encoding efficiency, the classification vector
|
|
is also partitioned into chunks. The integer elements of each scalar
|
|
in a classification chunk are built into a single scalar that
|
|
represents the classification numbers in that chunk. In the below
|
|
example, the classification codeword encodes two classification
|
|
numbers.<p>
|
|
|
|
<li>The values in a residue vector may be encoded monolithically in a
|
|
single pass through the residue vector, but more often efficient
|
|
codebook design dictates that each vector is encoded as the additive
|
|
sum of several passes through the residue vector using more than one
|
|
VQ codebook. Thus, each residue value potentially accumulates values
|
|
from multiple decode passes. The classification value associated with
|
|
a partition is the same in each pass, thus the classification codeword
|
|
is coded only in the first pass.<p>
|
|
|
|
</ul>
|
|
|
|
<img src="residue-pack.png"><p>
|
|
|
|
<h2>residue 0</h2>
|
|
|
|
Residue 0 and 1 differ only in the way the values within a residue
|
|
partition are interleaved during partition encoding (visually treated
|
|
as a black box- or cyan box or brown box- in the above figure).<p>
|
|
|
|
Residue encoding 0 interleaves VQ encoding according to the
|
|
dimension of the codebook used to encode a partition in a specific
|
|
pass. The dimension of the codebook need not be the same in multiple
|
|
passes, however the partition size must be an even multiple of the
|
|
codebook dimension.<p>
|
|
|
|
As an example, assume a partition vector of size eight, to be encoded
|
|
by residue 0 using codebook sizes of 8, 4, 2 and 1:<p>
|
|
|
|
<pre>
|
|
|
|
original residue vector: [ 0 1 2 3 4 5 6 7 ]
|
|
|
|
codebook dimensions = 8 encoded as: [ 0 1 2 3 4 5 6 7 ]
|
|
|
|
codebook dimensions = 4 encoded as: [ 0 2 4 6 ], [ 1 3 5 7 ]
|
|
|
|
codebook dimensions = 2 encoded as: [ 0 4 ], [ 1 5 ], [ 2 6 ], [ 3 7 ]
|
|
|
|
codebook dimensions = 1 encoded as: [ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ]
|
|
|
|
</pre>
|
|
|
|
It is worth mentioning at this point that no configurable value in the
|
|
residue coding setup is restricted to a power of two.<p>
|
|
|
|
<h2> residue 1 </h2>
|
|
|
|
Residue 1 does not interleave VQ encoding. It represents partition
|
|
vector scalars in order. As with residue 0, however, partition length
|
|
must be an integer multiple of the codebook dimension, although
|
|
dimension may vary from pass to pass.
|
|
|
|
As an example, assume a partition vector of size eight, to be encoded
|
|
by residue 0 using codebook sizes of 8, 4, 2 and 1:<p>
|
|
|
|
<pre>
|
|
|
|
original residue vector: [ 0 1 2 3 4 5 6 7 ]
|
|
|
|
codebook dimensions = 8 encoded as: [ 0 1 2 3 4 5 6 7 ]
|
|
|
|
codebook dimensions = 4 encoded as: [ 0 1 2 3 ], [ 4 5 6 7 ]
|
|
|
|
codebook dimensions = 2 encoded as: [ 0 1 ], [ 2 3 ], [ 4 5 ], [ 6 7 ]
|
|
|
|
codebook dimensions = 1 encoded as: [ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ]
|
|
|
|
</pre>
|
|
|
|
<h2> residue 2 </h2>
|
|
|
|
Residue type two can be thought of as a variant of residue type 1.
|
|
Rather than encoding multiple passed-in vectors as in residue type 1,
|
|
the <i>ch</i> passed in vectors of length <i>n</i> are first
|
|
interleaved and flattened into a single vector of length
|
|
<i>ch</i>*<i>n</i>. Encoding then proceeds as in type 1. Decoding is
|
|
as in type 1 with decode interleave reversed. If operating on a single
|
|
vector to begin with, residue type 1 and type 2 are equivalent.<p>
|
|
|
|
<img src="residue2.png"><p>
|
|
|
|
<h1>Residue decode</h1>
|
|
|
|
<h2>header decode</h2>
|
|
|
|
Header decode for all three residue types is identical.<p>
|
|
<pre>
|
|
1) [residue_begin] = read 24 bits as unsigned integer
|
|
2) [residue_end] = read 24 bits as unsigned integer
|
|
3) [residue_partition_size] = read 24 bits as unsigned integer and add one
|
|
4) [residue_classifications] = read 6 bits as unsigned integer and add one
|
|
5) [residue_classbook] = read 8 bits as unsigned integer
|
|
</pre>
|
|
|
|
<tt>[residue_begin]</tt> and <tt>[residue_end]</tt> select the specific
|
|
sub-portion of each vector that is actually coded; it implements akin
|
|
to a bandpass where, for coding purposes, the vector effectively
|
|
begins at element <tt>[residue_begin]</tt> and ends at
|
|
<tt>[residue_end]</tt>. Preceding and following values in the unpacked
|
|
vectors are zeroed. Note that for residue type 2, these values as
|
|
well as <tt>[residue_partition_size]</tt>apply to the interleaved
|
|
vector, not the individual vectors before interleave.
|
|
<tt>[residue_partition_size]</tt> is as explained above,
|
|
<tt>[residue_classifications]</tt> is the number of possible
|
|
classification to which a partition can belong and
|
|
<tt>[residue_classbook]</tt> is the codebook number used to code
|
|
classification codewords. The number of dimensions in book
|
|
<tt>[residue_classbook]</tt> determines how many classification values
|
|
are grouped into a single classification codeword.<p>
|
|
|
|
Next we read a bitmap pattern that specifies which partition classes
|
|
code values in which passes.<p>
|
|
|
|
<pre>
|
|
1) iterate [i] over the range 0 ... [residue_classifications]-1 {
|
|
|
|
2) [high_bits] = 0
|
|
3) [low_bits] = read 3 bits as unsigned integer
|
|
4) [bitflag] = read one bit as boolean
|
|
5) if ( [bitflag] is set ) then [high_bits] = read five bits as unsigned integer
|
|
6) vector [residue_cascade] element [i] = [high_bits] * 8 + [low_bits]
|
|
}
|
|
7) done
|
|
</pre>
|
|
|
|
Finally, we read in a list of book numbers, each corresponding to
|
|
specific bit set in the cascade bitmap. We loop over the possible
|
|
codebook classifications and the maximum possible number of encoding
|
|
stages (8 in Vorbis I, as constrained by the elements of the cascade
|
|
bitmap being eight bits):<p>
|
|
|
|
<pre>
|
|
1) iterate [i] over the range 0 ... [residue_classifications]-1 {
|
|
|
|
2) iterate [j] over the range 0 ... 7 {
|
|
|
|
3) if ( vector [residue_cascade] element [i] bit [j] is set ) {
|
|
|
|
4) array [residue_books] element [i][j] = read 8 bits as unsigned integer
|
|
|
|
} else {
|
|
|
|
5) array [residue_books] element [i][j] = unused
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
6) done
|
|
</pre>
|
|
|
|
An end-of-packet condition at any point in header decode renders the
|
|
stream undecodable. In addition, any codebook number greater than the
|
|
maximum numbered codebook set up in this stream also renders the
|
|
stream undecodable.<p>
|
|
|
|
<h2>packet decode</h2>
|
|
|
|
Format 0 and 1 packet decode is identical except for specific
|
|
partition interleave. Format 2 packet decode can be built out of the
|
|
format 1 decode process. Thus we describe first the decode
|
|
infrastructure identical to all three formats.<p>
|
|
|
|
In addition to configuration information, the residue decode process
|
|
is passed the number of vectors in the submap bundle and a vector of
|
|
flags indicating if any of the vectors are not to be decoded. If the
|
|
passed in number of vectors is 3 and vector number 1 is marked 'do not
|
|
decode', decode skips vector 1 during the decode loop. However, even
|
|
'do not decode' vectors are allocated and zeroed.<p>
|
|
|
|
The following convenience values are conceptually useful to clarifying
|
|
the decode process:<p>
|
|
|
|
<pre>
|
|
1) [classvals_per_codeword] = [codebook_dimensions] value of codebook [residue_classbook]
|
|
2) [n_to_read] = [residue_end] - [residue-begin]
|
|
3) [partitions_to_read] = [n_to_read] / [residue_partition_size]
|
|
</pre>
|
|
|
|
Packet decode proceeds as follows, matching the description offered earlier in the document. We assume that the number of vectors being encoded, <tt>[ch]</tt> is provided by the higher level decoding process.<p>
|
|
<pre>
|
|
1) allocate and zero all vectors that will be returned.
|
|
2) iterate [pass] over the range 0 ... 7 {
|
|
|
|
3) [partition_count] = 0
|
|
4) if ([pass] is zero) {
|
|
|
|
5) iterate [j] over the range 0 .. [ch]-1 {
|
|
|
|
6) if vector [j] is not marked 'do not decode' {
|
|
|
|
7) [temp] = read from packet using codebook [residue_classbook] in scalar context
|
|
8) iterate [k] descending over the range [classvals_per_codeword]-1 ... 0 {
|
|
|
|
9) array [classifications] element [j],([partition_count]+[k]) =
|
|
[temp] integer modulo [residue_classifications]
|
|
10) [temp] = [temp] / [residue_classifications] using integer division
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
11) [classword_count] = 0
|
|
12) iterate [j] over the range 0 .. [ch]-1 {
|
|
|
|
13) if vector [j] is not marked 'do not decode' {
|
|
|
|
|
|
14) [vqclass] = array [classifications] element [j],([partition_count]+[classword_count])
|
|
15) [vqbook] = array [residue_books] element [vqclass],[pass]
|
|
16) if ([vqbook] is not 'unused') {
|
|
|
|
17) decode partition into output vector number [j], starting at scalar
|
|
offset [residue_begin]+[partition_count]*[residue_partition_size] using
|
|
codebook number [vqbook] in VQ context
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
18) increment [classword_count]
|
|
19) increment [partition_count]
|
|
20) if ([classword_count] is less than [classvals_per_codeword]) AND
|
|
([partition_count] is less than [partitions_to_read) then continue at step 11
|
|
21) if ([partition_count] is less than [partitions_to_read) then continue at step 4
|
|
}
|
|
|
|
22) done
|
|
|
|
</pre>
|
|
|
|
An end-of-packet condition during packet decode is to be considered a
|
|
nominal occurrence. Decode returns the result of vector decode up to
|
|
that point.<p>
|
|
|
|
<h2>format 0 specifics</h2>
|
|
|
|
Format zero decodes partitions exactly as described earlier in the
|
|
'Residue Format: residue 0' section. The following pseudocode
|
|
presents the same algorithm. Assume:<p>
|
|
|
|
<ul>
|
|
<li> <tt>[n]</tt> is the value in
|
|
<tt>[residue_partition_size]</tt>
|
|
<li><tt>[v]</tt> is the residue vector
|
|
<li><tt>[offset]</tt> is the beginning read offset in [v]
|
|
</ul>
|
|
|
|
<pre>
|
|
1) [step] = [n] / [codebook_dimensions]
|
|
2) iterate [i] over the range 0 ... [step]-1 {
|
|
|
|
3) vector [entry_temp] = read vector from packet using current codebook in VQ context
|
|
4) iterate [j] over the range 0 ... [codebook_dimensions]-1 {
|
|
|
|
5) vector [v] element ([offset]+[i]+[j]*[step]) =
|
|
vector [v] element ([offset]+[i]+[j]*[step]) +
|
|
vector [entry_temp] element [j]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
6) done
|
|
|
|
</pre>
|
|
<p>
|
|
|
|
|
|
<h2>format 1 specifics</h2>
|
|
|
|
Format 1 decodes partitions exactly as described earlier in the
|
|
'Residue Format: residue 1' section. The following pseudocode
|
|
presents the same algorithm. Assume:<p>
|
|
|
|
<ul>
|
|
<li> <tt>[n]</tt> is the value in
|
|
<tt>[residue_partition_size]</tt>
|
|
<li><tt>[v]</tt> is the residue vector
|
|
<li><tt>[offset]</tt> is the beginning read offset in [v]
|
|
</ul>
|
|
|
|
<pre>
|
|
1) [i] = 0
|
|
2) vector [entry_temp] = read vector from packet using current codebook in VQ context
|
|
3) iterate [j] over the range 0 ... [codebook_dimensions]-1 {
|
|
|
|
5) vector [v] element ([offset]+[i]) =
|
|
vector [v] element ([offset]+[i]) +
|
|
vector [entry_temp] element [j]
|
|
6) increment [i]
|
|
|
|
}
|
|
|
|
4) if ( [i] is less than [n] ) continue at step 2
|
|
5) done
|
|
</pre>
|
|
<p>
|
|
|
|
<h2>format 2 specifics</h2>
|
|
|
|
Format 2 is reducible to format 1 through the following steps, performed in order: <p>
|
|
|
|
<ol>
|
|
<li>Assume format 2 is to decode <i>ch</i> vectors of length <i>n</i>.
|
|
<li>Decode, using format 1, a single vector <tt>[v]</tt>of length <i>ch</i>*<i>n</i>.
|
|
<li>Deinterleave this single vector <tt>[v]</tt> into <i>ch</i> independent vectors according to:<p>
|
|
<pre>
|
|
1) iterate [i] over the range 0 ... [n]-1 {
|
|
|
|
2) iterate [j] over the range 0 ... [ch]-1 {
|
|
|
|
3) output vector number [j] element [i] = vector [t] element ([i] * [ch] +[j])
|
|
|
|
}
|
|
}
|
|
|
|
4) done
|
|
</pre>
|
|
</ol>
|
|
<p>
|
|
|
|
Format 2 handles 'do not decode' vectors differently that residue 0 or
|
|
1; if all vectors are marked 'do not decode', no decode occurrs.
|
|
However, if at least one vector is to be decoded, all the vectors are
|
|
decoded.<p>
|
|
|
|
<hr>
|
|
<a href="http://www.xiph.org/">
|
|
<img src="white-xifish.png" align=left border=0>
|
|
</a>
|
|
<font size=-2 color=#505050>
|
|
|
|
Ogg is a <a href="http://www.xiph.org">Xiph.org Foundation</a> effort
|
|
to protect essential tenets of Internet multimedia from corporate
|
|
hostage-taking; Open Source is the net's greatest tool to keep
|
|
everyone honest. See <a href="http://www.xiph.org/about.html">About
|
|
the Xiph.org Foundation</a> for details.
|
|
<p>
|
|
|
|
Ogg Vorbis is the first Ogg audio CODEC. Anyone may freely use and
|
|
distribute the Ogg and Vorbis specification, whether in a private,
|
|
public or corporate capacity. However, the Xiph.org Foundation and
|
|
the Ogg project (xiph.org) reserve the right to set the Ogg Vorbis
|
|
specification and certify specification compliance.<p>
|
|
|
|
Xiph.org's Vorbis software CODEC implementation is distributed under a
|
|
BSD-like license. This does not restrict third parties from
|
|
distributing independent implementations of Vorbis software under
|
|
other licenses.<p>
|
|
|
|
Ogg, Vorbis, Xiph.org Foundation and their logos are trademarks (tm)
|
|
of the <a href="http://www.xiph.org/">Xiph.org Foundation</a>. These
|
|
pages are copyright (C) 1994-2002 Xiph.org Foundation. All rights
|
|
reserved.<p>
|
|
|
|
</body>
|
|
|