Blame doc/09-helper.tex

Packit 06404a
% -*- mode: latex; TeX-master: "Vorbis_I_spec"; -*-
Packit 06404a
%!TEX root = Vorbis_I_spec.tex
Packit 06404a
% $Id$
Packit 06404a
\section{Helper equations} \label{vorbis:spec:helper}
Packit 06404a
Packit 06404a
\subsection{Overview}
Packit 06404a
Packit 06404a
The equations below are used in multiple places by the Vorbis codec
Packit 06404a
specification.  Rather than cluttering up the main specification
Packit 06404a
documents, they are defined here and referenced where appropriate.
Packit 06404a
Packit 06404a
Packit 06404a
\subsection{Functions}
Packit 06404a
Packit 06404a
\subsubsection{ilog} \label{vorbis:spec:ilog}
Packit 06404a
Packit 06404a
The "ilog(x)" function returns the position number (1 through n) of the highest set bit in the two's complement integer value
Packit 06404a
\varname{[x]}.  Values of \varname{[x]} less than zero are defined to return zero.
Packit 06404a
Packit 06404a
\begin{programlisting}
Packit 06404a
  1) [return\_value] = 0;
Packit 06404a
  2) if ( [x] is greater than zero ) {
Packit 06404a
Packit 06404a
       3) increment [return\_value];
Packit 06404a
       4) logical shift [x] one bit to the right, padding the MSb with zero
Packit 06404a
       5) repeat at step 2)
Packit 06404a
Packit 06404a
     }
Packit 06404a
Packit 06404a
   6) done
Packit 06404a
\end{programlisting}
Packit 06404a
Packit 06404a
Examples:
Packit 06404a
Packit 06404a
\begin{itemize}
Packit 06404a
 \item ilog(0) = 0;
Packit 06404a
 \item ilog(1) = 1;
Packit 06404a
 \item ilog(2) = 2;
Packit 06404a
 \item ilog(3) = 2;
Packit 06404a
 \item ilog(4) = 3;
Packit 06404a
 \item ilog(7) = 3;
Packit 06404a
 \item ilog(negative number) = 0;
Packit 06404a
\end{itemize}
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
\subsubsection{float32\_unpack} \label{vorbis:spec:float32:unpack}
Packit 06404a
Packit 06404a
"float32\_unpack(x)" is intended to translate the packed binary
Packit 06404a
representation of a Vorbis codebook float value into the
Packit 06404a
representation used by the decoder for floating point numbers.  For
Packit 06404a
purposes of this example, we will unpack a Vorbis float32 into a
Packit 06404a
host-native floating point number.
Packit 06404a
Packit 06404a
\begin{programlisting}
Packit 06404a
  1) [mantissa] = [x] bitwise AND 0x1fffff (unsigned result)
Packit 06404a
  2) [sign] = [x] bitwise AND 0x80000000 (unsigned result)
Packit 06404a
  3) [exponent] = ( [x] bitwise AND 0x7fe00000) shifted right 21 bits (unsigned result)
Packit 06404a
  4) if ( [sign] is nonzero ) then negate [mantissa]
Packit 06404a
  5) return [mantissa] * ( 2 ^ ( [exponent] - 788 ) )
Packit 06404a
\end{programlisting}
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
\subsubsection{lookup1\_values} \label{vorbis:spec:lookup1:values}
Packit 06404a
Packit 06404a
"lookup1\_values(codebook\_entries,codebook\_dimensions)" is used to
Packit 06404a
compute the correct length of the value index for a codebook VQ lookup
Packit 06404a
table of lookup type 1.  The values on this list are permuted to
Packit 06404a
construct the VQ vector lookup table of size
Packit 06404a
\varname{[codebook\_entries]}.
Packit 06404a
Packit 06404a
The return value for this function is defined to be 'the greatest
Packit 06404a
integer value for which \varname{[return\_value]} to the power of
Packit 06404a
\varname{[codebook\_dimensions]} is less than or equal to
Packit 06404a
\varname{[codebook\_entries]}'.
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
\subsubsection{low\_neighbor} \label{vorbis:spec:low:neighbor}
Packit 06404a
Packit 06404a
"low\_neighbor(v,x)" finds the position \varname{n} in vector \varname{[v]} of
Packit 06404a
the greatest value scalar element for which \varname{n} is less than
Packit 06404a
\varname{[x]} and vector \varname{[v]} element \varname{n} is less
Packit 06404a
than vector \varname{[v]} element \varname{[x]}.
Packit 06404a
Packit 06404a
\subsubsection{high\_neighbor} \label{vorbis:spec:high:neighbor}
Packit 06404a
Packit 06404a
"high\_neighbor(v,x)" finds the position \varname{n} in vector [v] of
Packit 06404a
the lowest value scalar element for which \varname{n} is less than
Packit 06404a
\varname{[x]} and vector \varname{[v]} element \varname{n} is greater
Packit 06404a
than vector \varname{[v]} element \varname{[x]}.
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
\subsubsection{render\_point} \label{vorbis:spec:render:point}
Packit 06404a
Packit 06404a
"render\_point(x0,y0,x1,y1,X)" is used to find the Y value at point X
Packit 06404a
along the line specified by x0, x1, y0 and y1.  This function uses an
Packit 06404a
integer algorithm to solve for the point directly without calculating
Packit 06404a
intervening values along the line.
Packit 06404a
Packit 06404a
\begin{programlisting}
Packit 06404a
  1)  [dy] = [y1] - [y0]
Packit 06404a
  2) [adx] = [x1] - [x0]
Packit 06404a
  3) [ady] = absolute value of [dy]
Packit 06404a
  4) [err] = [ady] * ([X] - [x0])
Packit 06404a
  5) [off] = [err] / [adx] using integer division
Packit 06404a
  6) if ( [dy] is less than zero ) {
Packit 06404a
Packit 06404a
       7) [Y] = [y0] - [off]
Packit 06404a
Packit 06404a
     } else {
Packit 06404a
Packit 06404a
       8) [Y] = [y0] + [off]
Packit 06404a
Packit 06404a
     }
Packit 06404a
Packit 06404a
  9) done
Packit 06404a
\end{programlisting}
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
\subsubsection{render\_line} \label{vorbis:spec:render:line}
Packit 06404a
Packit 06404a
Floor decode type one uses the integer line drawing algorithm of
Packit 06404a
"render\_line(x0, y0, x1, y1, v)" to construct an integer floor
Packit 06404a
curve for contiguous piecewise line segments. Note that it has not
Packit 06404a
been relevant elsewhere, but here we must define integer division as
Packit 06404a
rounding division of both positive and negative numbers toward zero.
Packit 06404a
Packit 06404a
Packit 06404a
\begin{programlisting}
Packit 06404a
  1)   [dy] = [y1] - [y0]
Packit 06404a
  2)  [adx] = [x1] - [x0]
Packit 06404a
  3)  [ady] = absolute value of [dy]
Packit 06404a
  4) [base] = [dy] / [adx] using integer division
Packit 06404a
  5)    [x] = [x0]
Packit 06404a
  6)    [y] = [y0]
Packit 06404a
  7)  [err] = 0
Packit 06404a
Packit 06404a
  8) if ( [dy] is less than 0 ) {
Packit 06404a
Packit 06404a
        9) [sy] = [base] - 1
Packit 06404a
Packit 06404a
     } else {
Packit 06404a
Packit 06404a
       10) [sy] = [base] + 1
Packit 06404a
Packit 06404a
     }
Packit 06404a
Packit 06404a
 11) [ady] = [ady] - (absolute value of [base]) * [adx]
Packit 06404a
 12) vector [v] element [x] = [y]
Packit 06404a
Packit 06404a
 13) iterate [x] over the range [x0]+1 ... [x1]-1 {
Packit 06404a
Packit 06404a
       14) [err] = [err] + [ady];
Packit 06404a
       15) if ( [err] >= [adx] ) {
Packit 06404a
Packit 06404a
             16) [err] = [err] - [adx]
Packit 06404a
             17)   [y] = [y] + [sy]
Packit 06404a
Packit 06404a
           } else {
Packit 06404a
Packit 06404a
             18) [y] = [y] + [base]
Packit 06404a
Packit 06404a
           }
Packit 06404a
Packit 06404a
       19) vector [v] element [x] = [y]
Packit 06404a
Packit 06404a
     }
Packit 06404a
\end{programlisting}
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a
Packit 06404a