Commit completed first-draft of Vorbis I spec.
authorMonty <xiphmont@xiph.org>
Fri, 19 Jul 2002 08:48:31 +0000 (08:48 +0000)
committerMonty <xiphmont@xiph.org>
Fri, 19 Jul 2002 08:48:31 +0000 (08:48 +0000)
svn path=/trunk/vorbis/; revision=3682

doc/vorbis-spec-floor0.html
doc/vorbis-spec-floor1.html
doc/vorbis-spec-intro.html
doc/vorbis-spec-ref.html
doc/vorbis-spec-res.html

index e01fa54e8e93bf7a23a55482a018e23bef3a50a7..b2ecc15563613f718100efd6ad507e2d9aba614e 100644 (file)
@@ -6,7 +6,7 @@
 Ogg Vorbis I format specification: floor type 0 setup and decode
 </font></h1>
 
-<em>Last update to this document: July 18, 2002</em><br>
+<em>Last update to this document: July 19, 2002</em><br>
 
 <h1>Overview</h1>
 
@@ -48,7 +48,8 @@ this stream undecodable.  In addition, any element of the array
 number for this bitstream is an error condition that also renders the
 stream undecodable.
 
-<h2>packet decode</h2>
+<a name=decode>
+<h2>packet decode</h2></a>
 
 Extracting a floor0 curve from an audio packet consists of first
 decoding the curve amplitude and <tt>[floor0_order]</tt> LSP
@@ -103,7 +104,8 @@ 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.
 </ul>
  
-<h2>curve computation</h2>
+<a name=synth>
+<h2>curve computation</h2></a>
 
 Given an <tt>[amplitude]</tt> integer and <tt>[coefficients]</tt>
 vector from packet decode as well as the [floor0_order],
index e513bf28a9d04449f266949aef33f2ee68f36502..22d3fd95858f377717a18900d042db3b6ca33c28 100644 (file)
@@ -6,7 +6,7 @@
 Ogg Vorbis I format specification: floor type 1 setup and decode
 </font></h1>
 
-<em>Last update to this document: July 18, 2002</em><br>
+<em>Last update to this document: July 19, 2002</em><br>
 
 <h1>Overview</h1>
 
@@ -146,7 +146,8 @@ addition, a <tt>[floor1_class_masterbooks]</tt> or
 highest numbered codebook configured in this stream is an error
 condition that renders the stream undecodable.<p>
 
-<h2>packet decode</h2>
+<a name=decode>
+<h2>packet decode</h2></a>
 
 Packet decode begins by checking the <tt>[nonzero]</tt> flag:<p>
 
@@ -211,7 +212,8 @@ operation above, floor decode is to return 'unused' status as if the
 Vector <tt>[floor1_Y]</tt> contains the values from packet decode
 needed for floor 1 synthesis.<p>
 
-<h2>curve computation</h2>
+<a name=synth>
+<h2>curve computation</h2></a>
 
 Curve computation is split into two logical steps; the first step
 derives final Y amplitude values from the encoded, wrapped difference
index 5d948d97b95c57b3d433539c2f030ed4404871fb..b9aa7592c79127cbbfc059a566b9acfa9efdc999 100644 (file)
@@ -329,7 +329,8 @@ as described earlier, all of which may be used in a given Vorbis
 stream. The mode is encoded as an integer used as a direct offset into
 the mode instance index. <p>
 
-<h3>Window shape decode [long windows only]</h3>
+<a name=window>
+<h3>Window shape decode [long windows only]</h3></a>
 
 Vorbis frames may be one of two PCM sample sizes specified during
 codec setup.  In Vorbis I, legal frame sizes are powers of two from 64
@@ -369,7 +370,7 @@ can be found in the paper <a
 href="http://www.iocon.com/resource/docs/ps/eusipco_corrected.ps">_The
 use of multirate filter banks for coding of high quality digital
 audio_</a>, by T. Sporer, K. Brandenburg and B. Edler.  Vorbis windows
-all use the slope function y=sin(2PI*sin^2((x+.5)/n)).<p>
+all use the slope function y=sin(2PI*sin^2(x/n)).<p>
 
 <h3>floor decode</h3>
 
@@ -429,9 +430,8 @@ This step is straightforward; for each output channel, the decoder
 multiplies the floor curve and residue vectors element by element,
 producing the finished audio spectrum of each channel.<p>
 
-One point is worth mentioning about this dot product (the bit-level
-specification document goes into more detail about this); a common
-mistake in a fixed point implementation is to assume that a 32 bit
+One point is worth mentioning about this dot product; a common mistake
+in a fixed point implementation might be to assume that a 32 bit
 fixed-point representation for floor and residue and direct
 multiplication of the vectors is sufficient for acceptable spectral
 depth in all cases because it happens to mostly work with the current
@@ -494,7 +494,7 @@ transform orthogonality.  Pay attention however to returning the
 correct data range; the amount of data to be returned is:<p>
 <tt>window_blocksize(previous_window)/4+window_blocksize(current_window)/4</tt>
 from the center of the previous window to the center of the current
-window..<p>
+window.<p>
 
 Data is not returned from the first frame; it must be used to 'prime'
 the decode engine.  The encoder accounts for this priming when
index 60d97e26e7f3d860e95f30413d54b53810083ea8..cff82de247845919c936f49bf9febc6c47e9f698 100644 (file)
@@ -46,7 +46,7 @@ identification, comment, setup.
 <h2>Identification Header</h2>
 
 The identification header is a short header of only a few fields used
-to declare the stream definitively as Vorbis, and provide a externally
+to declare the stream definitively as Vorbis, and provide a few externally
 relevant pieces of information about the audio stream. The
 identification header is coded as follows:<p>
 
@@ -54,22 +54,32 @@ identification header is coded as follows:<p>
  1) [vorbis_version] = read 32 bits as unsigned integer
  2) [audio_channels] = read 8 bit integer as unsigned
  3) [audio_sample_rate] = read 32 bits as unsigned integer
- 4) [bitrate_maximum] = read 32 bits as unsigned integer
- 5) [bitrate_nominal] = read 32 bits as unsigned integer
- 6) [bitrate_lower] = read 32 bits as unsigned integer
+ 4) [bitrate_maximum] = read 32 bits as signed integer
+ 5) [bitrate_nominal] = read 32 bits as signed integer
+ 6) [bitrate_lower] = read 32 bits as signed integer
  7) [blocksize_0] = 2 exponent (read 4 bits as unsigned integer)
  8) [blocksize_1] = 2 exponent (read 4 bits as unsigned integer)
  9) [framing_flag] = read one bit
 </pre>
 
-<tt>[vorbis_version]</tt> is to read '0' in order to be compatable
-with this docuement.  Both <tt>[audio_channels]</tt> and
+<tt>[vorbis_version]</tt> is to read '0' in order to be compatible
+with this document.  Both <tt>[audio_channels]</tt> and
 <tt>[audio_rate]</tt> must read greater than zero.  Allowed final
 blocksize values are 64, 128, 256, 512, 1024, 2048, 4096 and 8192 in
 Vorbis I.  <tt>[blocksize_0]</tt> must be less than or equal to
 <tt>[blocksize_1]</tt>.  The framing bit must be nonzero.  Failure to
 meet any of these conditions renders a stream undecodable.<p>
 
+The bitrate fields above are used only as hints. The nominal bitrate
+field especially may be considerably off in purely VBR streams.  The
+fields are meaningful only when greater than zero.<p>
+<ul><li>All three fields set to the same value implies a fixed rate, or tightly bounded, nearly fixed-rate bitstream
+    <li>Only nominal set implies a VBR or ABR stream that averages the nominal bitrate
+    <li>Upper and or lower set implies a VBR bitstream that obeys the bitrate limits
+    <li>None set indicates the encoder does not care to speculate.
+</ul>
+
+
 <h2>Comment Header</h2>
 
 Comment header decode and data specification is covered in <a
@@ -86,7 +96,7 @@ The setup header contains the bulk of the codec setup information
 needed for decode.  The setup header contains, in order, the lists of
 codebook configurations, time-domain transform configurations
 (placeholders in Vorbis I), floor configurations, residue
-configurations, channel mappping configurations and mode
+configurations, channel mapping configurations and mode
 configurations. It finishes with a framing bit of '1'.  Header decode
 proceeds in the following order:<p>
 
@@ -108,12 +118,12 @@ sync.<p>
 
 <ol>
 <li><tt>[vorbis_time_count]</tt> = read 6 bits as unsigned integer and add one
-<li>read <tt>[vorbis_time_count]</tt> 16 bit values; each value should be zero.  If any othe values is nonzero, this is an error condition and the stream is undecodable.
+<li>read <tt>[vorbis_time_count]</tt> 16 bit values; each value should be zero.  If any other values is nonzero, this is an error condition and the stream is undecodable.
 </ol>
 
 <h3>floors</h3>
 
-Vorbis uses two floor type; header decode is handed to the decode
+Vorbis uses two floor types; header decode is handed to the decode
 abstraction of the appropriate type.
 
 <ol>
@@ -159,12 +169,12 @@ uses a single mapping type (0), with implicit PCM channel mappings.<p>
                  <li>if unset, <tt>[vorbis_mapping_submaps]</tt> = 1<p>
              </ol>
           <li>read 1 bit as a boolean flag; if set, square polar channel mapping is in use:<p>
-              <ol><li><tt>[vorbis_mapping_coupling_steps]</tt>= read 8 bits as unsigned int and add one<p>
+              <ol><li><tt>[vorbis_mapping_coupling_steps]</tt>= read 8 bits as unsigned integer and add one<p>
                   <li>for <tt>[j]</tt> each of <tt>[vorbis_mapping_coupling_steps]</tt> steps:<p>
                       <ol>
-                      <li>vector <tt>[vorbis_mapping_magnitude]</tt> element <tt>[j]</tt>= read <a href="helper.html#ilog">ilog</a>([audio_channels]) bits as unsiged integer<p>
-                      <li>vector <tt>[vorbis_mapping_angle]</tt> element <tt>[j]</tt>= read <a href="helper.html#ilog">ilog</a>([audio_channels]) bits as unsiged integer<p>
-                      <li>the numbers read in the above two steps are channel numbers representing the channel to treat as magnitude and the channel to treat as angle, respectively.  If any of angle channel equals magnitud channel, magnitude channel is greater than <tt>[audio_channels]</tt>-1, or angle channel is greater than <tt>[audio_channels]</tt>-1, the stream is undecodable.<p>
+                      <li>vector <tt>[vorbis_mapping_magnitude]</tt> element <tt>[j]</tt>= read <a href="helper.html#ilog">ilog</a>([audio_channels]) bits as unsigned integer<p>
+                      <li>vector <tt>[vorbis_mapping_angle]</tt> element <tt>[j]</tt>= read <a href="helper.html#ilog">ilog</a>([audio_channels]) bits as unsigned integer<p>
+                      <li>the numbers read in the above two steps are channel numbers representing the channel to treat as magnitude and the channel to treat as angle, respectively.  If any of angle channel equals magnitude channel, magnitude channel is greater than <tt>[audio_channels]</tt>-1, or angle channel is greater than <tt>[audio_channels]</tt>-1, the stream is undecodable.<p>
                       </ol>
                </ol>
            <li>read 2 bits (reserved field); if the value is nonzero, the stream is undecodable<p>
@@ -176,7 +186,7 @@ uses a single mapping type (0), with implicit PCM channel mappings.<p>
               <ol><li>read and discard 8 bits (the unused time configuration placeholder)<p>
                   <li>read 8 bits as unsigned integer for the floor number; save in vector <tt>[vorbis_mapping_submap_floor]</tt> element <tt>[j]</tt><p>
                   <li>verify the floor number is not greater than the highest number floor configured for the bitstream.  If it is, the bitstream is undecodable<p>
-                  <li>read 8 bits as unsigned integer for the residue number; save in vector <tt>[vorbis_mapping_submapping_residue]</tt> element <tt>[j]</tt><p>
+                  <li>read 8 bits as unsigned integer for the residue number; save in vector <tt>[vorbis_mapping_submap_residue]</tt> element <tt>[j]</tt><p>
                   <li>verify the residue number is not greater than the highest number residue configured for the bitstream.  If it is, the bitstream is undecodable<p>
               </ol>
 
@@ -190,14 +200,16 @@ uses a single mapping type (0), with implicit PCM channel mappings.<p>
 <h3>modes</h3>
 
 <ol>
-<li><tt>[vorbis_mode_count]</tt> = read 6 bits as unsigned integer and add one
-<li>For each of <tt>[vorbis_mode_count]</tt> mode numbers:
+<li><tt>[vorbis_mode_count]</tt> = read 6 bits as unsigned integer and add one<p.
+<li>For each of <tt>[vorbis_mode_count]</tt> mode numbers:<p>
   <ol>
   <li><tt>[vorbis_mode_blockflag]</tt> = read 1 bit<p>
   <li><tt>[vorbis_mode_windowtype]</tt> = read 16 bits as unsigned integer<p>
   <li><tt>[vorbis_mode_transformtype]</tt> = read 16 bits as unsigned integer<p>
   <li><tt>[vorbis_mode_mapping]</tt> = read 8 bits as unsigned integer<p>
   <li>verify ranges; zero is the only legal value in Vorbis I for <tt>[vorbis_mode_windowtype]</tt> and <tt>[vorbis_mode_transformtype]</tt>.  <tt>[vorbis_mode_mapping]</tt> must not be greater than the highest number mapping in use.  Any illegal values render the stream undecodable.<p>
+  <li>save this mode configuration in slot <tt>[i]</tt> of the mode configuration array <tt>[vorbis_mode_configurations]</tt>.<p>
+
   </ol>
   <li>read 1 bit as a framing flag.  If unset, a framing error occurred and the stream is not decodable.
 
@@ -205,12 +217,287 @@ uses a single mapping type (0), with implicit PCM channel mappings.<p>
 
 After reading mode descriptions, setup header decode is complete.<p>
 
-<h1>Packet decode</h1>
+<h1>Audio packet decode and synthesis</h1>
 
+Following the three header packets, all packets in a Vorbis I stream
+are audio.  The first step of audio packet decode is to read and
+verify the packet type; <em>a non-audio packet when audio is expected
+indicates stream corruption or a non-compliant stream. The decoder
+must ignore the packet and not attempt decoding it to audio</em>.
+
+<h2>packet type, mode and window decode</h2>
+
+<ol>
+<li>read 1 bit <tt>[packet_type]</tt>; check that packet type is 0 (audio)<p>
+<li>read <a href="helper.html#ilog">ilog</a>([vorbis_mode_count]-1) bits <tt>[mode_number]</tt><p>
+<li>decode blocksize <tt>[n]</tt> is equal to <tt>[blocksize_0]</tt> if  <tt>[vorbis_mode_blockflag]</tt> is 0, else <tt>[n]</tt> is equal to <tt>[blocksize_1]</tt><p.
+<li>perform window selection and setup; this window is used later by the inverse MDCT:<p>
+   <ol><li>if this is a long window (the <tt>[vorbis_mode_blockflag]</tt> flag of this mode is set):<p>
+       <ol>
+         <li>read 1 bit for <tt>[previous_window_flag]</tt><p>
+         <li>read 1 bit for <tt>[next_window_flag]</tt><p>
+
+         <li>if <tt>[previous_window_flag]</tt> is not set, the left half
+         of the window will be a hybrid window for lapping with a
+         short block.  See <a href="vorbis-spec-intro.html#window">the
+         'Window' subheading of the specification introduction
+         document</a> for an illustration of overlapping dissimilar
+         windows. Else, the left half window will have normal long
+         shape.<p>
+
+         <li>if <tt>[next_window_flag]</tt> is not set, the right half of
+         the window will be a hybrid window for lapping with a short
+         block.  See <a href="vorbis-spec-intro.html#window">the
+         'Window' subheading of the specification introduction
+         document</a> for an illustration of overlapping dissimilar
+         windows. Else, the left right window will have normal long
+         shape.<p>
+       </ol>
+       <li> if this is a short window, the window is always the same 
+       short-window shape.<p>
 
-<h4>channel order</h4>
+  </ol>
+</ol>
+
+Vorbis windows all use the slope function y=sin(2*PI*sin^2(x/n)),
+but dissimilar lapping requirements can affect overall shape.  Window
+generation proceeds as follows:<p>
+
+<ol>
+<li> <tt>[window_center]</tt> = <tt>[n]</tt> / 2
+<li> <tt>[left_window_start]</tt>
+<li> if (<tt>[vorbis_mode_blockflag]</tt> is set and <tt>[previous_window_flag]</tt> is not set) then 
+    <ol><li><tt>[left_window_start]</tt> = <tt>[n]</tt>/4 - <tt>[blocksize_0]</tt>/4
+        <li><tt>[left_window_end]</tt> = <tt>[n]</tt>/4 + <tt>[blocksize_0]</tt>/4
+        <li><tt>[left_n]</tt> = <tt>[blocksize_0]</tt>/2
+    </ol>
+    else
+    <ol><li><tt>[left_window_start]</tt> = 0
+        <li><tt>[left_window_end]</tt> = <tt>[window_center]</tt>
+        <li><tt>[left_n]</tt> = <tt>[n]</tt>/2
+    </ol>
+
+<li> if (<tt>[vorbis_mode_blockflag]</tt> is set and <tt>[next_window_flag]</tt> is not set) then 
+    <ol><li><tt>[right_window_start]</tt> = <tt>[n]*3</tt>/4 - <tt>[blocksize_0]</tt>/4
+        <li><tt>[right_window_end]</tt> = <tt>[n]*3</tt>/4 + <tt>[blocksize_0]</tt>/4
+        <li><tt>[right_n]</tt> = <tt>[blocksize_0]</tt>/2
+    </ol>
+    else
+    <ol><li><tt>[right_window_start]</tt> = <tt>[window_center]</tt>
+        <li><tt>[right_window_end]</tt> = <tt>[n]</tt>
+        <li><tt>[right_n]</tt> = <tt>[n]</tt>/2
+    </ol>
+<li> window from range 0 ... <tt>[left_window_start]</tt>-1 inclusive is zero
+
+<li> for <tt>[i]</tt> in range <tt>[left_window_start]</tt> ... <tt>[left_window_end]</tt>-1, window(<tt>[i]</tt>) = sin(2*PI*sin^2((<tt>[i]</tt>-<tt>[left_window_start]</tt>+.5)/<tt>[left_n]</tt>*PI/2))
+
+
+<li> window from range <tt>[left_window_end]</tt> ... <tt>[right_window_start]</tt>-1 inclusive is one
+
+<li> for <tt>[i]</tt> in range <tt>[right_window_start]</tt> ... <tt>[right_window_end]</tt>-1, window(<tt>[i]</tt>) = sin(2*PI*sin^2((<tt>[i]</tt>-<tt>[right_window_start]</tt>+.5)/<tt>[right_n]</tt>*PI/2.+PI/2.))
+
+<li> window from range <tt>[rigth_window_start]</tt> ... <tt>[n]</tt>-1 is zero
+
+</ol><p>
+
+An end-of-packet condition up to this point should be considered an
+error that discards this packet from the stream.  An end of packet
+condition past this point is to be considered a possible nominal
+occurrence.<p>
+
+
+<h2>floor curve decode</h2>
+
+From this point on, we assume out decode context is using mode number
+<tt>[mode_number]</tt> from configuration array
+<tt>[vorbis_mode_configurations]</tt> and the map number
+<tt>[vorbis_mode_mapping]</tt> (specified by the current mode) taken
+from the mapping configuration array
+<tt>[vorbis_mapping_configurations]</tt>.<p>
+
+Floor curves are decoded one-by-one in channel order.<p>
+
+For each floor <tt>[i]</tt> of <tt>[audio_channels]</tt>
+  <ol><li><tt>[submap_number]</tt> = element <tt>[i]</tt> of vector [vorbis_mapping_mux] <p>
+
+      <li><tt>[floor_number]</tt> = element <tt>[submap_number]</tt> of vector [vorbis_submap_floor]<p>
+      <li>if the floor type of this floor (vector <tt>[vorbis_floor_types]</tt> element <tt>[floor_number]</tt>) is zero then decode the floor for channel <tt>[i]</tt> according to the <a href="vorbis-spec-floor0.html#decode">floor 0 decode algorithm</a><p>
+      <li>if the type of this floor is one then decode the floor for channel <tt>[i]</tt> according to the <a href="vorbis-spec-floor1.html#decode">floor 1 decode algorithm</a><p>
+      <li>save the needed decoded floor information for channel for later synthesis<p>
+      <li>if the decoded floor returned 'unused', set vector <tt>[no_residue]</tt> element <tt>[i]</tt> to true, else set vector <tt>[no_residue]</tt> element <tt>[i]</tt> to false<p>
+</ol>
 
-In mapping type 0, channel mapping is implicitly defined as follows for standard audio applications:<p>
+An end-of-packet condition during floor decode shall result in packet
+decode zeroing all channel output vectors and skipping to the
+add/overlap output stage.<p>
+
+<h2>nonzero vector propagate</h2>
+
+A possible result of floor decode is that a specific vector is marked
+'unused' which indicates that that final output vector is all-zero
+values (and the floor is zero).  The residue for that vector is not
+coded in the stream, save for one complication.  If some vectors are
+used and some are not, channel coupling could result in mixing a
+zeroed and nonzeroed vector to produce two nonzeroed vectors.<p>
+
+for each <tt>[i]</tt> from 0 ... <tt>[vorbis_mapping_coupling_steps]</tt>-1
+
+<ol><li>if either <tt>[no_residue]</tt> entry for channel
+(<tt>[vorbis_mapping_magnitude]</tt> element <tt>[i]</tt>) or (channel
+<tt>[vorbis_mapping_angle]</tt> element <tt>[i]</tt>) are set to false, then both
+must be set to false.  Note that an 'unused' floor has no decoded floor
+information; it is important that this is remembered at floor curve
+synthesis time.
+</ol>
+
+<h2>residue decode</h2>
+
+Unlike floors, which are decoded in channel order, the residue vectors
+are decoded in submap order.<p>
+
+for each submap <tt>[i]</tt> in order from 0 ... <tt>[vorbis_mapping_submaps]</tt>-1<p>
+<ol><li><tt>[ch]</tt> = 0<p>
+    <li>for each channel <tt>[j]</tt> in order from 0 ... <tt>[audio_channels]</tt><p>
+        <ol><li>if channel <tt>[j]</tt> is in submap <tt>[i]</tt> (vector <tt>[vorbis_mapping_mux]</tt> element <tt>[j]</tt> is equal to <tt>[i]</tt>)<p>
+           <ol><li>if vector <tt>[no_residue]</tt> element <tt>[j]</tt> is true<p>
+                <ol><li>vector <tt>[do_not_decode_flag]</tt> element <tt>[channels_in_bundle]</tt> is set<p>
+               </ol>else<ol><li>vector <tt>[do_not_decode_flag]</tt> element <tt>[channels_in_bundle]</tt> is unset<p>
+                </ol>
+                <li>increment <tt>[ch]</tt><p>
+             </ol>
+         </ol>
+     <li><tt>[residue_number]</tt> = vector <tt>[vorbis_mapping_submap_residue]</tt> element <tt>[i]</tt><p>
+
+     <li><tt>[residue_type]</tt> = vector <tt>[vorbis_residue_types]</tt> element <tt>[residue_number]</tt><p>
+     <li>decode <tt>[ch]</tt> vectors using residue <tt>[residue_number]</tt>, according to type <tt>[residue_type]</tt>, also passing vector <tt>[do_not_decode_flag]</tt> to indicate which vectors in the bundle should not be decoded. Correct per-vector decode length is <tt>[n]</tt>/2.<p>
+           
+    <li><tt>[ch]</tt> = 0<p>
+    <li>for each channel <tt>[j]</tt> in order from 0 ... <tt>[audio_channels]</tt><p>
+        <ol><li>if channel <tt>[j]</tt> is in submap <tt>[i]</tt> (vector <tt>[vorbis_mapping_mux]</tt> element <tt>[j]</tt> is equal to <tt>[i]</tt>)<p>
+           <ol><li>residue vector for channel <tt>[j]</tt> is set to decoded residue vector <tt>[ch]</tt><p>
+               <li>increment <tt>[ch]</tt>
+            </ol>
+         </ol>
+</ol>
+
+<h2>inverse coupling</h2>
+
+for each <tt>[i]</tt> from <tt>[vorbis_mapping_coupling_steps]</tt>-1 descending to 0
+
+<ol>
+
+<li><tt>[magnitude_vector]</tt> = the residue vector for channel
+(vector <tt>[vorbis_mapping_magnitude]</tt> element <tt>[i]</tt>)
+
+<li><tt>[angle_vector]</tt> = the residue vector for channel (vector
+<tt>[vorbis_mapping_angle]</tt> element <tt>[i]</tt>)
+
+<li>for each scalar value <tt>[M]</tt> in vector <tt>[magnitude_vector]</tt> and the corresponding scalar value <tt>[A]</tt> in vector <tt>[angle_vector]</tt>:
+   <ol><li>if (<tt>[M]</tt> is greater than zero)
+       <ol><li>if (<tt>[A]</tt> is greater than zero)
+           <ol>
+               <li><tt>[new_M]</tt> = <tt>[M]</tt>
+               <li><tt>[new_A]</tt> = <tt>[M]</tt>-<tt>[A]</tt>
+           </ol>
+           else
+           <ol>
+               <li><tt>[new_A]</tt> = <tt>[M]</tt>
+               <li><tt>[new_M]</tt> = <tt>[M]</tt>+<tt>[A]</tt>
+           </ol>
+        </ol>
+        else
+        <ol><li>if (<tt>[A]</tt> is greater than zero)
+           <ol>
+               <li><tt>[new_M]</tt> = <tt>[M]</tt>
+               <li><tt>[new_A]</tt> = <tt>[M]</tt>+<tt>[A]</tt>
+           </ol>
+           else
+           <ol>
+               <li><tt>[new_A]</tt> = <tt>[M]</tt>
+               <li><tt>[new_M]</tt> = <tt>[M]</tt>-<tt>[A]</tt>
+           </ol>
+        </ol><p>
+
+       <li>set scalar value <tt>[M]</tt> in vector <tt>[magnitude_vector]</tt> to <tt>[new_M]</tt>
+       <li>set scalar value <tt>[A]</tt> in vector <tt>[angle_vector]</tt> to <tt>[new_A]</tt>
+    </ol>
+</ol>
+
+<h2>dot product</h2>
+
+For each channel, synthesize the floor curve from the decoded floor
+information, according to packet type. Note that the vector synthesis
+length for floor computation is <tt>[n]</tt>/2.<p>
+
+For each channel, multiply each element of the floor curve by each
+element of that channel's residue vector.  The result is the dot
+product the floor and residue vectors for each channel; the produced
+vectors are the length <tt>[n]</tt>/2 audio spectrum for each
+channel.<p>
+
+One point is worth mentioning about this dot product; a common mistake
+in a fixed point implementation might be to assume that a 32 bit
+fixed-point representation for floor and residue and direct
+multiplication of the vectors is sufficient for acceptable spectral
+depth in all cases because it happens to mostly work with the current
+Xiph.Org reference encoder. <p>
+
+However, floor vector values can span ~140dB (~24 bits unsigned), and
+the audio spectrum vector should represent a minimum of 120dB (~21
+bits with sign), even when output is to a 16 bit PCM device.  For the
+residue vector to represent full scale if the floor is nailed to
+-140dB, it must be able to span 0 to +140dB.  For the residue vector
+to reach full scale if the floor is nailed at 0dB, it must be able to
+represent -140dB to +0dB.  Thus, in order to handle full range
+dynamics, a residue vector may span -140dB to +140dB entirely within
+spec.  A 280dB range is approximately 48 bits with sign; thus the
+residue vector must be able to represent a 48 bit range and the dot
+product must be able to handle an effective 48 bit times 24 bit
+multiplication.  This range may be achieved using large (64 bit or
+larger) integers, or implementing a movable binary point
+representation.<p>
+
+<h2>inverse MDCT</h2>
+
+Convert the audio spectrum vector of each channel back into time
+domain PCM audio via an inverse Modified Discrete Cosine Transform
+(MDCT).  A detailed description of the MDCT is available in the paper
+<a
+href="http://www.iocon.com/resource/docs/ps/eusipco_corrected.ps">_The
+use of multirate filter banks for coding of high quality digital
+audio_</a>, by T. Sporer, K. Brandenburg and B. Edler.  The window
+function used for the MDCT is the window determined earlier.<p>
+
+<h2>overlap_add</h2>
+
+Windowed MDCT output is overlapped and added with the right hand data
+of the previous window such that the 3/4 point of the previous window
+is aligned with the 1/4 point of the current window (as illustrated in
+<a href="vorbis-spec-intro.html#window">the 'Window' portion of the
+specification introduction document</a>.  The overlapped portion
+produced from overlapping the previous and current frame data is
+finished data to be returned by the decoder.  This data spans from the
+center of the previous window to the center of the current window.  In
+the case of same-sized windows, the amount of data to return is
+one-half block consisting of and only of the overlapped portions. When
+overlapping a short and long window, much of the returned range is not
+actually overlap.  This does not damage transform orthogonality.  Pay
+attention however to returning the correct data range; the amount of
+data to be returned is:<p>
+<tt>window_blocksize(previous_window)/4+window_blocksize(current_window)/4</tt>
+from the center (element windowsize/2) of the previous window to the
+center (element windowsize/2-1, inclusive) of the current window.<p>
+
+Data is not returned from the first frame; it must be used to 'prime'
+the decode engine.  The encoder accounts for this priming when
+calculating PCM offsets; after the first frame, the proper PCM output
+offset is '0' (as no data has been returned yet).<p>
+
+<h2>output channel order</h2>
+
+Vorbis I specifies only a channel mapping type 0.  In mapping type 0,
+channel mapping is implicitly defined as follows for standard audio
+applications:<p>
 
 <dl>
 <dt>one channel:<dd> the stream is monophonic
@@ -219,16 +506,13 @@ In mapping type 0, channel mapping is implicitly defined as follows for standard
 <dt>four channels:<dd> the stream is quadraphonic surround.  channel order: front left, front right, rear left, rear right
 <dt>five channels:<dd> the stream is five-channel surround.  channel order: front left, front center, front right, rear left, rear right
 <dt>six channels:<dd> the stream is 5,1 surround.  channel order: front left, front center, front right, rear left, rear right, LFE
-<dt>greter than six channels:<dd> channel use and order is defined by the application
+<dt>greater than six channels:<dd> channel use and order is defined by the application
 </dl>
 
-Applications using vorbis for dedicated purposes may define channel
+Applications using Vorbis for dedicated purposes may define channel
 mapping as seen fit.  Future channel mappings (such as three and four
 channel <a href="http://www.ambisonic.net">Ambisonics</a>) will make
-use of channel mappings other than mapping 0.
-
-
-
+use of channel mappings other than mapping 0.<p>
 
 <hr>
 <a href="http://www.xiph.org/">
index 9e957afe0445f5a9c05adf685580add1a77c5111..15008430f60f794e2b9a981a50878c2c99c7a7aa 100644 (file)
@@ -6,7 +6,7 @@
 Ogg Vorbis I format specification: residue setup and decode
 </font></h1>
 
-<em>Last update to this document: July 18, 2002</em><br>
+<em>Last update to this document: July 19, 2002</em><br>
 
 <h1>Overview</h1>
 
@@ -221,6 +221,13 @@ 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>
 
@@ -240,40 +247,49 @@ Packet decode proceeds as follows, matching the description offered earlier in t
      
             5) iterate [j] over the range 0 .. [ch]-1 {
 
-                 6) [temp] = read from packet using codebook [residue_classbook] in scalar context
-                 7) iterate [k] descending over the range [classvals_per_codeword]-1 ... 0 {
+                 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 {
 
-                      8) array [classifications] element [j],([partition_count]+[k]) =
-                         [temp] integer modulo [residue_classifications]
-                      9) [temp] = [temp] / [residue_classifications] using integer division
+                           9) array [classifications] element [j],([partition_count]+[k]) =
+                              [temp] integer modulo [residue_classifications]
+                          10) [temp] = [temp] / [residue_classifications] using integer division
 
+                         }
+      
                     }
-               }
             
+               }
+        
           }
 
-      10) [classword_count] = 0
-      11) iterate [j] over the range 0 .. [ch]-1 {
+      11) [classword_count] = 0
+      12) iterate [j] over the range 0 .. [ch]-1 {
 
-            12) [vqclass] = array [classifications] element [j],([partition_count]+[classword_count])
-            13) [vqbook] = array [residue_books] element [vqclass],[pass]
-            14) if ([vqbook] is not 'unused') {
+            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
+                     }
+               }
 
-                  15) 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
-                }
           }
 
-      16) increment [classword_count]
-      17) increment [partition_count]
-      18) if ([classword_count] is less than [classvals_per_codeword]) AND 
+      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
-      19) if ([partition_count] is less than [partitions_to_read) then continue at step 4
+      21) if ([partition_count] is less than [partitions_to_read) then continue at step 4
     }
  
- 20) done
+ 22) done
 
 </pre>
 
@@ -368,6 +384,11 @@ Format 2 is reducible to format 1 through the following steps, performed in orde
 </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>