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