$Id: 06-floor0.xml 8547 2004-12-29 03:33:51Z giles $

# Floor type 0 setup and decode

## Overview

Vorbis floor type zero uses Line Spectral Pair (LSP, also alternately known as Line Spectral Frequency or LSF) representation to encode a smooth spectral envelope curve as the frequency response of the LSP filter. This representation is equivalent to a traditional all-pole infinite impulse response filter as would be used in linear predictive coding; LSP representation may be converted to LPC representation and vice-versa.

## Floor 0 format

Floor zero configuration consists of six integer fields and a list of VQ codebooks for use in coding/decoding the LSP filter coefficient values used by each frame.

### header decode

Configuration information for instances of floor zero decodes from the codec setup header (third packet). configuration decode proceeds as follows:

      1) [floor0_order] = read an unsigned integer of 8 bits
      2) [floor0_rate] = read an unsigned integer of 16 bits
      3) [floor0_bark_map_size] = read an unsigned integer of 16 bits
      4) [floor0_amplitude_bits] = read an unsigned integer of six bits
      5) [floor0_amplitude_offset] = read an unsigned integer of eight bits
      6) [floor0_number_of_books] = read an unsigned integer of four bits and add 1
      7) if any of [floor0_order], [floor0_rate], [floor0_bark_map_size], [floor0_amplitude_bits],
         [floor0_amplitude_offset] or [floor0_number_of_books] are less than zero, the stream is not decodable
      8) array [floor0_book_list] = read a list of [floor0_number_of_books] unsigned integers of eight bits each;

An end-of-packet condition during any of these bitstream reads renders this stream undecodable. In addition, any element of the array `[floor0_book_list]` that is greater than the maximum codebook number for this bitstream is an error condition that also renders the stream undecodable.

### packet decode

Extracting a floor0 curve from an audio packet consists of first decoding the curve amplitude and `[floor0_order]` LSP coefficient values from the bitstream, and then computing the floor curve, which is defined as the frequency response of the decoded LSP filter.

Packet decode proceeds as follows:

      1) [amplitude] = read an unsigned integer of [floor0_amplitude_bits] bits
      2) if ( [amplitude] is greater than zero ) {
           3) [coefficients] is an empty, zero length vector

           4) [booknumber] = read an unsigned integer of ilog( [floor0_number_of_books] ) bits
           5) if ( [booknumber] is greater than the highest number decode codebook ) then packet is undecodable
           6) [last] = zero;
           7) vector [temp_vector] = read vector from bitstream using codebook number [booknumber] in VQ context.
           8) add the scalar value [last] to each scalar in vector [temp_vector]
           9) [last] = the value of the last scalar in vector [temp_vector]
          10) concatenate [temp_vector] onto the end of the [coefficients] vector
          11) if (length of vector [coefficients] is less than [floor0_order], continue at step 6

         }

     12) done.

Take note of the following properties of decode:

- An `[amplitude]` value of zero must result in a return code that indicates this channel is unused in this frame (the output of the channel will be all-zeroes in synthesis). Several later stages of decode don't occur for an unused channel.

- An end-of-packet condition during decode should be considered a nominal occruence; if end-of-packet is reached during any read operation above, floor decode is to return 'unused' status as if the `[amplitude]` value had read zero at the beginning of decode.

- The book number used for decode can, in fact, be stored in the bitstream in ilog( `[floor0_number_of_books]` - 1 ) bits. Nevertheless, the above specification is correct and values greater than the maximum possible book value are reserved.

- The number of scalars read into the vector `[coefficients]` may be greater than `[floor0_order]`, the number actually required for curve computation. For example, if the VQ codebook used for the floor currently being decoded has a `[codebook_dimensions]` value of three and `[floor0_order]` is ten, the only way to fill all the needed scalars in `[coefficients]` is to to read a total of twelve scalars as four vectors of three scalars each. This is not an error condition, and care must be taken not to allow a buffer overflow in decode. The extra values are not used and may be ignored or discarded.

### curve computation

Given an `[amplitude]` integer and `[coefficients]` vector from packet decode as well as the [floor0_order], [floor0_rate], [floor0_bark_map_size], [floor0_amplitude_bits] and [floor0_amplitude_offset] values from floor setup, and an output vector size `[n]` specified by the decode process, we compute a floor output vector.

If the value `[amplitude]` is zero, the return value is a length `[n]` vector with all-zero scalars. Otherwise, begin by assuming the following definitions for the given vector to be synthesized:

[lsp map equation]
\begin{math} \mathrm{map}_i = \left\{ \begin{array}{ll} \min ( \mathtt{floor0\_bark\_map\_size} - 1, foobar ) & \textrm{for } i \in [0,n-1] \\ -1 & \textrm{for } i = n \end{array} \right. \end {math} where \begin{math} foobar = \left\lfloor \mathrm{bark}\left(\frac{\mathtt{floor0\_rate} \cdot i}{2n}\right) \cdot \frac{\mathtt{floor0\_bark\_map\_size}} {\mathrm{bark}(.5 \cdot \mathtt{floor0\_rate})} \right\rfloor \end{math} and \begin{math} \mathrm{bark}(x) = 13.1 \arctan (.00074x) + 2.24 \arctan (.0000000185x^2 + .0001x) \end{math}

The above is used to synthesize the LSP curve on a Bark-scale frequency axis, then map the result to a linear-scale frequency axis. Similarly, the below calculation synthesizes the output LSP curve `[output]` on a log (dB) amplitude scale, mapping it to linear amplitude in the last step:

1. `[i]` = 0

2. if ( `[floor0_order]` is odd ) {

   1. calculate `[p]` and `[q]` according to: [equation for odd lsp] \begin{eqnarray*} p & = & (1 - \cos^2\omega)\prod_{j=0}^{(\mathtt{order}-3)/2} 4 (\cos c_{2j+1} - \cos \omega)^2 \\ q & = & \frac{1}{4} \prod_{j=0}^{(\mathtt{order}-1)/2} 4 (\cos c_{2j+1} - \cos \omega)^2 \end{eqnarray*}

   } else `[floor0_order]` is even {

   1. calculate `[p]` and `[q]` according to: [equation for even lsp] \begin{eqnarray*} p & = & \frac{(1 - \cos^2\omega)}{2} \prod_{j=0}^{(\mathtt{order}-2)/2} 4 (\cos c_{2j} - \cos \omega)^2 \\ q & = & \frac{(1 + \cos^2\omega)}{2} \prod_{j=0}^{(\mathtt{order}-2)/2} 4 (\cos c_{2j} - \cos \omega)^2 \end{eqnarray*}

   }

3. calculate `[linear_floor_value]` according to: [expression for floorval] \begin{math} \exp \left( .11512925 \left(\frac{\mathtt{amplitude} \cdot \mathtt{floor0\_amplitute\_offset}}{(2^{\mathtt{floor0\_amplitude\_bits}}-1)\sqrt{p+q}} - \mathtt{floor0\_amplitude\_offset} \right) \right) \end{math}

4. `[iteration_condition]` = map element `[i]`

5. `[output]` element `[i]` = `[linear_floor_value]`

6. increment `[i]`

7. if ( map element `[i]` is equal to `[iteration_condition]` ) continue at step 5

8. if ( `[i]` is less than `[n]` ) continue at step 2

9. done