From 4710cd238ee1213c5f85774eea3e5da3212c7c11 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 19 Jul 1999 05:02:03 +0000 Subject: [PATCH] Bringing my development in line with CVS now that the repository is set up. Added beginning of HTML docs, and a semi-complete framing.c Monty 19990719 svn path=/trunk/vorbis/; revision=8 --- doc/framing.html | 385 ++++++++++++++++++++++++++++++++++++++++ doc/framing.txt | 293 ------------------------------- doc/oggstream.html | 193 ++++++++++++++++++++ doc/stream.gif | Bin 0 -> 3409 bytes doc/vorbis.html | 197 +++++++++++++++++++++ doc/vorbisword2.gif | Bin 0 -> 1464 bytes doc/wait.gif | Bin 0 -> 359 bytes doc/white-ogg.gif | Bin 0 -> 1232 bytes doc/white-xifish.gif | Bin 0 -> 943 bytes lib/analysis.c | 6 +- lib/codec.h | 73 +++++--- lib/envelope.c | 2 - lib/framing.c | 485 +++++++++++++++++++++++++++++++++++++++++++++------ lib/mdct.c | 15 +- lib/mdct.h | 2 - 15 files changed, 1271 insertions(+), 380 deletions(-) create mode 100644 doc/framing.html delete mode 100644 doc/framing.txt create mode 100644 doc/oggstream.html create mode 100644 doc/stream.gif create mode 100644 doc/vorbis.html create mode 100644 doc/vorbisword2.gif create mode 100644 doc/wait.gif create mode 100644 doc/white-ogg.gif create mode 100644 doc/white-xifish.gif diff --git a/doc/framing.html b/doc/framing.html new file mode 100644 index 0000000..d5707c2 --- /dev/null +++ b/doc/framing.html @@ -0,0 +1,385 @@ +xiph.org: OggSquish Vorbis documentation + +

+ +

+OggSquish logical bitstream framing +

+ +Last update to this document: July 15, 1999
+ +

OggSquish bitstreams

+ +Vorbis encodes short-time blocks of PCM data into raw packets of +bit-packed data. These raw packets may be used directly by transport +mechanisms that provide their own framing and packet-seperation +mechanisms (such as UDP datagrams). For stream based storage (such as +files) and transport (such as TCP streams or pipes), Vorbis uses the +OggSquish bitstream format to provide framing/sync, sync recapture +after error, landmarks during seeking, and enough information to +properly seperate data back into packets at the original packet +boundaries without relying on decoding to find packet boundaries.

+ +

Design constraints for OggSquish bitstreams

+ +
  1. True streaming; we must not need to seek to build a 100% + complete bitstream. + +
  2. Use no more than approximately 1-2% of bitstream bandwidth for + packet boundary marking, high-level framing, sync and seeking. + +
  3. Specification of absolute position within the original sample + stream. + +
  4. Simple mechanism to ease limited editing, such as a simplified + concatenation mechanism. + +
  5. Detection of corruption, recapture after error and direct, random + access to data at arbitrary positions in the bitstream. +
+ +

Logical and Physical Bitstreams

+ +A logical OggSquish bitstream is a contiguous stream of +sequential pages belonging only to the logical bitstream. A +physical OggSquish bitstream is constructed from one or more +than one logical OggSquish bitstream (the simplest physical bitstream +is simply a single logical bitstream). We describe below the exact +formatting of an OggSquish logical bitstream. Combining logical +bitstreams into more complex physical bitstreams is described in the +OggSquish bitstream overview. The exact +mapping of raw Vorbis packets into a valid Ogg Vorbis physical +bitstream is described in Vorbis +bitstream mapping. + +

Bitstream structure

+ +An OggSquish stream is structured by dividing incoming packets into +segments of up to 255 bytes and then wrapping a group of contiguous +packet segments into a variable length page preceeded by a page +header. Both the header size and page size are variable; the page +header contains sizing information and checksum data to determine +header/page size and data integrity.

+ +The bitstream is captured (or recaptured) by looking for the beginning +of a page, specifically the capture pattern. Once the capture pattern +is found, the decoder verifies page sync and integrity by computing +and comparing the checksum. At that point, the decoder can extract the +packets themselves.

+ +

Packet segmentation

+ +Packets are logically divided into multiple segments before encoding +into a page. Note that the segmentation and fragmentation process is a +logical one; it's used to compute page header values and the original +page data need not be disturbed, even when a packet spans page +boundaries.

+ +The raw packet is logically divided into [n] 255 byte segments and a +last fractional segment of < 255 bytes. A packet size may well +consist only of the trailing fractional segment, and a fractional +segment may be zero length. These values, called "lacing values" are +then saved and placed into the header segment table.

+ +An example should make the basic concept clear:

+ +

+
+raw packet:
+  ___________________________________________
+ |______________packet data__________________| 753 bytes
+
+lacing values for page header segment table: 255,255,243
+
+
+ +We simply add the lacing values for the total size; the last lacing +value for a packet is always the value that is less than 255. Note +that this encoding both avoids imposing a maximum packet size as well +as imposing minimum overhead on small packets (as opposed to, eg, +simply using two bytes at the head of every packet and having a max +packet size of 32k. Small packets (<255, the typical case) are +penalized with twice the segmentation overhead). Using the lacing +values as suggested, small packets see the minimum possible +byte-aligned overheade (1 byte) and large packets, over 512 bytes or +so, see a fairly constant ~.5% overhead on encoding space.

+ +Note that a lacing value of 255 implies that a second lacing value +follows in the packet, and a value of < 255 marks the end of the +packet after that many additional bytes. A packet of 255 bytes (or a +multiple of 255 bytes) is terminated by a lacing value of 0:

+ +


+raw packet:
+  _______________________________
+ |________packet data____________|          255 bytes
+
+lacing values: 255, 0
+
+ +Note also that a 'nil' (zero length) packet is not an error; it +consists of nothing more than a lacing value of zero in the header.

+ +

Packets spanning pages

+ +Packets are not resticted to beginning and ending within a page, +although individual segments are, by definition, required to do so. +Packets are not restricted to a maximum size, although excessively +large packets in the data stream are discouraged; the OggSquish +bitstream specification strongly recommends nominal page size of +approximately 4-8kB (large packets are forseen as being useful for +initialization data at the beginning of a logical bitstream).

+ +After segmenting a packet, the encoder may decide not to place all the +resulting segments into the current page; to do so, the encoder places +the lacing values of the segments it wishes to belong to the current +page into the current segment table, then finishes the page. The next +page is begun with the first value in the segment table belonging to +the next packet segment, thus continuing the packet (data in the +packet body must also correspond properly to the lacing values in the +spanned pages. The segment data in the first packet corresponding to +the lacing values of the first page belong in that page; packet +segments listed in the segment table of the following page must begin +the page body of the subsequent page).

+ +The last mechanic to spanning a page boundary is to set the header +flag in the new page to indicate that the first lacing value in the +segment table continues rather than begins a packet; a header flag of +0x01 is set to indicate a continued packet. Although mandatory, it +is not actually algorithmically necessary; one could inspect the +preceeding segment table to determine if the packet is new or +continued. Adding the information to the packet_header flag allows a +simpler design (with no overhead) that needs only inspect the current +page header after frame capture. This also allows faster error +recovery in the event that the packet originates in a corrupt +preceeding page, implying that the previous page's segment table +cannot be trusted.

+ +Note that a packet can span an arbitrary number of pages; the above +spanning process is repeated for each spanned page boundary. Also a +'zero termination' on a packet size that is an even multiple of 255 +must appear even if the lacing value appears in the next page as a +zero-length continuation of the current packet. The header flag +should be set to 0x01 to indicate that the packet spanned, even though +the span is a nil case as far as data is concerned.

+ +The encoding looks odd, but is properly optimized for speed and the +expected case of the majority of packets being between 50 and 200 +bytes (note that it is designed such that packets of wildly different +sizes can be handled within the model; placing packet size +restrictions on the encoder would have only slightly simplified design +in page generation and increased overall encoder complexity).

+ +The main point behind tracking individual packets (and packet +segments) is to allow more flexible encoding tricks that requiring +explicit knowledge of packet size. An example is simple bandwidth +limiting, implemented by simply truncating packets in the nominal case +if the packet is arranged so that the least sensitive portion of the +data comes last.

+ +

Page header

+ +The headering mechanism is designed to avoid copying and re-assembly +of the packet data (ie, making the packet segmentation process a +logical one); the header can be generated directly from incoming +packet data. The encoder buffers packet data until it finishes a +complete page at which point it writes the header followed by the +buffered packet segments.

+ +

capture_pattern

+ + A header begins with a capture pattern that simplifies identifying + pages; once the decoder has found the capture pattern it can do a more + intensive job of verifying that it has in fact found a page boundary + (as opposed to an inadvertant coincidence in the byte stream).

+ +


+ byte value
+
+  0  0x4f 'O'
+  1  0x67 'g'
+  2  0x67 'g'
+  3  0x53 'S'  
+
+ +

stream_structure_version

+ + The capture pattern is followed by the stream structure revision: + +

+ byte value
+
+  4  0x00
+
+ +

header_type_flag

+ + The header type flag identifies this page's context in the bitstream: + +

+ byte value
+
+  5  bitflags: 0x01: unset = fresh packet
+	               set = continued packet
+	       0x02: unset = not first page of logical bitstream
+                       set = first page of logical bitstream (bos)
+	       0x04: unset = not last page of logical bitstream
+                       set = last page of logical bitstream (eos)
+
+ +

PCM absolute position

+ + (This is packed in the same way the rest of OggSquish data is packed; + LSb of LSB first. Note that the 'position' data specifies a 'sample' + number (eg, in a CD quality sample is four octets, 16 bits for left + and 16 bits for right; in video it would be the frame number). The + position specified is the total samples encoded after including all + packets finished on this page (packets begun on this page but + continuing on to thenext page do not count). The rationale here is + that the position specified in the frame header of the last page + tells how long the PCM data coded by the bitstream is. A truncated + stream will still return the proper number of samples that can be + decoded fully. + +

+ byte value
+
+  6  0xXX LSB
+  7  0xXX
+  8  0xXX
+  9  0xXX
+ 10  0xXX
+ 11  0xXX
+ 12  0xXX
+ 13  0xXX MSB
+
+ +

stream serial number

+ + OggSquish allows for seperate logical bitstreams to be mixed at page + granularity in a physical bitstream. The most common case would be + sequential arrangement, but it is possible to interleave pages for + two seperate bitstreams to be decoded concurrently. The serial + number is the means by which pages physical pages are associated with + a particular logical stream. Each logical stream must have a unique + serial number within a physical stream: + +

+ byte value
+
+ 14  0xXX LSB
+ 15  0xXX
+ 16  0xXX
+ 17  0xXX MSB
+
+ +

page sequence no

+ + Page counter; lets us know if a page is lost (useful where packets + span page boundaries). + +

+ byte value
+
+ 18  0xXX LSB
+ 19  0xXX
+ 20  0xXX
+ 21  0xXX MSB
+
+ +

page checksum

+ + 32 bit CRC value (direct algorithm, initial val and final XOR = 0, + generator polynomial=0x04c11db7). The value is computed over the + entire header (with the CRC field in the header set to zero) and then + continued over the page. The CRC field is then filled with the + computed value.

+ + (A thorough discussion of CRC algorithms can be found in "A + Painless Guide to CRC Error Detection Algorithms" by Ross + Williams ross@guest.adelaide.edu.au.) + +


+ byte value
+
+ 22  0xXX LSB
+ 23  0xXX
+ 24  0xXX
+ 25  0xXX MSB
+
+ +

page_segments

+ + The number of segment entries to appear in the segment table. The + maximum number of 255 segments (255 bytes each) sets the maximum + possible physical page size at 65307 bytes or just under 64kB (thus + we know that a header corrupted so as destroy sizing/alignment + information will not cause a runaway bitstream. We'll read in the + page according to the corrupted size information that's guaranteed to + be a reasonable size regardless, notice the checksum mismatch, drop + sync and then look for recapture).

+ +


+ byte value
+
+ 26 0x00-0xff (0-255)
+
+ +

segment_table (containing packet lacing values)

+ + The lacing values for each packet segment physically appearing in + this page are listed in contiguous order. + +

+ byte value
+
+ 27 0x00-0xff (0-255)
+ [...]
+ n  0x00-0xff (0-255, n=page_segments+26)
+
+ +Total page size is calculated directly from the known header size and +lacing values in the segment table. Packet data segments follow +immediately after the header.

+ +Page headers typically impose a flat .25-.5% space overhead assuming +nominal ~8k page sizes. The segmentation table needed for exact +packet recovery in the streaming layer adds approximately .5-1% +nominal assuming expected encoder behavior in the 44.1kHz, 128kbps +stereo encodings.

+ +


+ + + + + +OggSquish is a Xiphophorus 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 About +Xiphophorus for details. +

+ +Ogg Vorbis is the first OggSquish audio CODEC. Anyone may +freely use and distribute the OggSquish and Vorbis specification, +whether in a private, public or corporate capacity. However, +Xiphophorus and the Ogg project (xiph.org) reserve the right to set +the Ogg/Vorbis specification and certify specification compliance.

+ +Xiphophorus's Vorbis software CODEC implementation (libvorbis and the +vorbis encode/decode/playback utility) are distributed under the GNU +Public License. This does not restrict third parties from +distributing independent implementations of Vorbis software under +other licenses.

+ +OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of +Xiphophorus. These pages are +copyright (C) 1994-1999 Xiphophorus. All rights reserved.

+ + + + diff --git a/doc/framing.txt b/doc/framing.txt deleted file mode 100644 index 9872a03..0000000 --- a/doc/framing.txt +++ /dev/null @@ -1,293 +0,0 @@ -******************************************************************** -* * -* THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * -* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * -* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * -* PLEASE READ THESE TERMS DISTRIBUTING. * -* * -* THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 * -* by 1999 Monty and The XIPHOPHORUS Company * -* http://www.xiph.org/ * -* * -******************************************************************** - - function: discussion of Vorbis framing - author: Monty , - modifications by: Monty - last modification date: Jun 30 1999 - -******************************************************************** - -Vorbis encodes short-time blocks of PCM data into raw packets of -bit-packed data. These raw packets may be used directly by transport -mechanisms that provide their own framing and packet-seperation -mechanisms (such as UDP datagrams). For stream based storage (such as -files) and transport (such as TCP streams or pipes), Vorbis also -specifies an additional layer of bitstream structure to provide -framing/sync, sync recapture after error, landmarks during seeking, -and enough information to properly seperate data back into packets at -the original packet boundaries without relying on decoding to find -packet boundaries. - -Design constraints: - -1) True streaming; we must not need to seek to build a 100% complete - bitstream. - -2) Use no more than approximately 1-2% of bitstream bandwidth for packet - boundary marking, high-level framing, sync and seeking. - -3) Specification of absolute position within the original sample stream. - -4) Simple mechanism to ease limited editing, such as a simplified - concatenation mechanism. - -5) Detection of corruption and recapture after error. - -A vorbis stream is structured by dividing packets into segments of up -to 255 bytes and then wrapping a group of contiguous packet segments -into a variable length page preceeded by a page header. Both the -header size and page size are variable; the page header contains -sizing information and checksum data to determine header/page size and -data integrity. - -The bitstream is captured (or recaptured) by looking for the beginning -of a page, specifically the capture pattern. Once the capture pattern -is found, the decoder verifies page sync and integrity by computing -and comparing the checksum. At that point, the decoder can extract the -packetss themselves. - -**** Packet segmentation - -Packets are logically divided into multiple segments before encoding -into a page. Note that the segmentation and fragmentation process is a -logical one; it's used to compute page header values and the original -page data need not be disturbed, even when a packet spans page -boundaries. - -The raw packet is logically divided into [n] 255 byte segments and a -last fractional segment of < 255 bytes. A packet size may well -consist only of the trailing fractional segment, and a fractional -segment may be zero length. These values, called "lacing values" are -then saved and placed into the header segment table. - -An example should make the basic concept clear: - -raw packet: - ___________________________________________ - |______________packet data__________________| 753 bytes - -lacing values for page header segment table: 255,255,243 - -We simply add the lacing values for the total size; the last lacing -value for a packet is always the value that is less than 255. Note -that this encoding both avoids imposing a maximum packet size as well -as imposing minimum overhead on small packets (as opposed to, eg, -simply using two bytes at the head of every packet and having a max -packet size of 32k. Small packets (<255, the typical case) are -penalized with twice the segmentation overhead). Using the lacing -values as suggested, small packets see the minimum possible -byte-aligned overheade (1 byte) and large packets, over 512 bytes or -so, see a fairly constant ~.5% overhead on encoding space. - -Clarification of boundary cases: - -Note that a lacing value of 255 implies that a second lacing value -follows in the packet, and a value of < 255 marks the end of the -packet after that many additional bytes. A packet of 255 bytes (or a -multiple of 255 bytes) is terminated by a lacing value of 0: - -raw packet: - _______________________________ - |________packet data____________| 255 bytes - -lacing values: 255, 0 - -Note also that a 'nil' (zero length) packet is not an error; it -consists of nothing more than a lacing value of zero in the header. - -**** Packets spanning pages: - -Packets are not resticted to beginning and ending within a page, -although individual segments are, by definition, required to do so. -Packets are not restricted to a maximum size, although excessively -large packets in the data stream are discouraged; the Vorbis -specification strongly recommend nominal page size of approximately -4-8kB (large packets are forseen as being useful for initialization -data at the beginning of a logical bitstream). - -After segmenting a packet, the encoder may decide not to place all the -resulting segments into the current page; to do so, the encoder places -the lacing values of the segments it wishes to belong to the current -page into the current segment table, then finishes the page. The next -page is begun with the first value in the segment table belonging to -the next packet segment, thus continuing the packet (data in the -packet body must also correspond properly to the lacing values in the -spanned pages. The segment data in the first packet corresponding to the -lacing values of the first page belong in that page; packet segments listed in the segment table of the following page must begin the page body of the subsequent page). - -The last mechanic to spanning a page boundary is to set the header -flag in the new page to indicate that the first lacing value in the -segment table continues rather than begins a packet; a header flag of -0x02 is used to indicate a continued packet. Although mandatory, it -is not actually algorithmically necessary; one could inspect the -preceeding segment table to determine if the packet is new or -continued. Adding the information to the packet_header flag allows a -simpler design (with no overhead) that needs only inspect the current -page header after frame capture. This also allows faster error -recovery in the event that the packet originates in a corrupt -preceeding page, implying that the previous page's segment table -cannot be trusted. - -Note that a packet can span an arbitrary number of pages; the above -spanning process is repeated for each spanned page boundary. Also a -'zero termination' on a packet size that is an even multiple of 255 -must appear even if the lacing value appears in the next page as a -zero-length continuation of the current packet. The header flag -should be set to 0x02 to indicate that the packet spanned, even though -the span is a nil case as far as data is concerned. - -The encoding looks odd, but is properly optimized for speed and the -expected case of the majority of packets being between 50 and 200 -bytes (note that it is designed such that packets of wildly different -sizes can be handled within the model; placing packet size -restrictions on the encoder would have only slightly simplified design -in page generation and increased overall encoder complexity). - -The main point behind tracking individual packets (and packet -segments) is to allow more flexible encoding tricks that requiring -explicit knowledge of packet size. An example is simple bandwidth -limiting, implemented by simply truncating packets in the nominal case -(the packet is arranged so that the least sensitive portion of the -data comes last). - -**** Page header - -The headering mechanism is designed to avoid copying and re-assembly -of the packet data; the header can be generated directly from incoming -packet data. The encoder buffers packet data until it finishes a -complete page at which point it writes the header followed by the -buffered packet segments. - -capture_pattern: - - A header begins with a capture pattern that simplifies identifying - pages; once the decoder has found the capture pattern it can do a more - intensive job of verifying that it has in fact found a page boundary - (as opposed to an inadvertant coincidence in the byte stream). - - byte value - 0 0x4f 'O' - 1 0x67 'g' - 2 0x67 'g' - 3 0x53 'S' - -stream_structure_version: - - The capture pattern is followed by the stream structure revision: - - 4 0x00 - - -header_type_flag: - - The header type flag identifies this page's context in the bitstream: - - 5 0x00 (beginning of bitstream) - 0x01 (bitstream continued, fresh packet) - 0x02 (bitstream continued, continued packet) - -PCM absolute position - - (This is packed in the same way the rest of Vorbis packet data is - packed; LSb of LSB first. Note that the 'position' data specifies a - sample number (eg, in a CD quality sample is four octets, 16 bits for - left and 16 bits for right). The position specified is the total - samples encoded after including all packets begun in this page. The - rationale here is that the position specified in the frame header of - the last page tells how long the PCM data coded by the bitstream is. - - 6 0xXX LSB - 7 0xXX - 8 0xXX - 9 0xXX - 10 0xXX - 11 0xXX - 12 0xXX - 13 0xXX MSB - -stream serial number: - - Vorbis allows for seperate logical bitstreams to be mixed at page - granularity in a physical bitstream. The most common case would be - sequential arrangement, but it is possible to interleave pages for - two seperate bitstreams to be decoded concurrently. Right now, the - standard code doesn't use the serial number (sets it to zero), but it - will eventually. Each logical stream must have a unique serial - number within a physical stream: - - 14 0xXX LSB - 15 0xXX - 16 0xXX - 17 0xXX MSB - -page sequence no - - Page counter; lets us know if a page is lost (useful where packets - span page boundaries). - - 18 0xXX LSB - 19 0xXX - 20 0xXX - 21 0xXX MSB - -page checksum - - 32 bit CRC value (direct algorithm, initial val and final XOR = 0, - generator polynomial=0x04c11db7). The value is computed over the - entire header (with the CRC field in the header set to zero) and then - continued over the page. The CRC field is then filled with the - computed value. - - (A thorough discussion of CRC algorithms can be found in "A Painless - Guide to CRC Error Detection Algorithms" by Ross Williams - (ross@guest.adelaide.edu.au). The document is available from - ftp://ftp.adelaide.edu.au/pub/rocksoft) - - 22 0xXX LSB - 23 0xXX - 24 0xXX - 25 0xXX MSB - -page_segments - - The number of segment entries to appear in the segment table. The - maximum number of 255 segments (255 bytes each) sets the maximum - possible physical page size at 65307 bytes or just under 64kB (thus - we know that a header corrupted so as destroy sizing/alignment - information will not cause a runaway bitstream. We'll read in the - page according to the corrupted size information that's guaranteed to - be a reasonable size regardless, notice the checksum mismatch, drop - sync and then look for recapture). - - 26 0x00-0xff (0-255) - -segment_table (containing packet lacing values) - - The lacing values for each packet segment physically appearing in - this page are listed in contiguous order. - - 27 0x00-0xff (0-255) - [...] - n 0x00-0xff (0-255, n=page_segments+26) - -Total page size is calculated directly from the known header size and -lacing values in the segment table. Packet data segments follow -immediately after the header. - -Page headers typically impose a flat .25-.5% space overhead assuming -nominal ~8k page sizes. The segmentation table needed for exact -packet recovery in the streaming layer adds approximately .5-1% -nominal assuming expected encoder behavior in the 44.1kHz, 128kbps -stereo encodings. - diff --git a/doc/oggstream.html b/doc/oggstream.html new file mode 100644 index 0000000..2980c6d --- /dev/null +++ b/doc/oggstream.html @@ -0,0 +1,193 @@ +xiph.org: OggSquish Vorbis documentation + +

+ + +

+OggSquish logical and physical bitstream overview +

+ +Last update to this document: July 18, 1999
+ +

OggSquish bitstreams

+ +OggSquish codecs use octet vectors of raw, compressed data +(packets). These compressed packets do not have any +high-level structure or boundary information; strung together, they +appear to be streams of random bytes with no landmarks.

+ +Raw packets may be used directly by transport mechanisms that provide +their own framing and packet-seperation mechanisms (such as UDP +datagrams). For stream based storage (such as files) and transport +(such as TCP streams or pipes), Vorbis and other future Ogg codecs use +the OggSquish bitstream format to provide framing/sync, sync recapture +after error, landmarks during seeking, and enough information to +properly seperate data back into packets at the original packet +boundaries without relying on decoding to find packet boundaries.

+ +

Logical and physical bitstreams

+ +Raw packets are grouped and encoded into contiguous pages of +structured bitstream data called logical bitstreams. A +logical bitstream consists of pages, in order, belonging to a single +codec instance. Each page is a self contained entity (although it is +possible that a packet may be split and encoded across one or more +pages); that is, the page decode mechanism is designed to recognize, +verify and handle single pages at a time from the overall bitstream.

+ +Multiple logical bitstreams can be combined (with restricctions) into +a single physical bitstream. A physical bitstream consists +of multiple logical bitstreams multiplexed at the page level. Whole +pages are taken in order from multiple logical bitstreams and combined +into a single physical stream of pages. The decoder reconstructs the +original logical bitstreams from the physical bitstream by taking the +pages in order fromt he physical bitstream and redirecting them into +the appropriate logical decoding entitiy. The simplest physical +bitstream is a single, unmultiplexed logical bitstream.

+ +OggSquish Logical Bitstream Framing discusses +the page format of an OggSquish bitstream, the packet coding process +and logical bitstreams in detail. The remainder of this document +specifies requirements for constructing finished, physical OggSquish +bitstreams.

+ +

Mapping Restrictions

+ +Logical bitstreams may not be mapped/multiplexed into physical +bitstreams without restriction. Here we discuss design restrictions +on OggSquish physical bitstreams in general, mostly to introduce +design rationale. Each 'media' format defines its own (generally more +restrictive) mapping. An 'Ogg Vorbis +Audio Bitstream', for example, has a specific physical bitstream structure. +An 'Ogg A/V' bitstream (not currently specified) will also mandate a +specific, restricted physical bitstream format.

+ +

additional end-to-end structure

+ +The framing specification defines +'beginning of stream' and 'end of stream' page markers via a header +flag (it is possible for a stream to consist of a single page). A +stream always consists of an integer number of pages, an easy +requirement given the variable size nature of pages.

+ +In addition to the header flag marking the first and last pages of a +logical bitstream, the first page of an OggSquish bitstream obeys +additional restrictions. Each individual media mapping specifies its +own implementation details regarding these restrictions.

+ +The first page of a logical OggSquish bitstream consists of a single, +small 'initial header' packet that includes sufficient information to +identify the exact CODEC type and media requirements of the logical +bitstream. The intent of this restriction is to simplify identifying +the bitstream type and content; for a given media type (or across all +OggSquish media types) we can know that we only need a small, fixed +amount of data to uniquely identify the bitstream type.

+ +As an example, Ogg Vorbis places the name and revision of the Vorbis +CODEC, the audio rate and the audio quality into this initial header, +thus simplifying vastly the certain identification of an Ogg Vorbis +audio bitstream.

+ +

sequential multiplexing (chaining)

+ +The simplest form of logical bitstream multiplexing is concatenation +(chaining). Complete logical bitstreams are strung +one-after-another in order. The bitstreams do not overlap; the final +page of a given logical bitstream is immediately followed by the +initial page of the next. Chaining is the only logical->physical +mapping allowed by Ogg Vorbis.

+ +Each chained logical bitstream must have a unique serial number within +the scope of the physical bitstream.

+ +

concurrent multiplexing (grouping)

+ +Logical bitstreams may also be multiplexed 'in parallel' +(grouped). An example of grouping would be to allow +streaming of seperate audio and video streams, using differnt codecs +and different logical bitstreams, in the same physical bitstream. +Whole pages from multiple logical bitstreams are mixed together.

+ +The initial pages of each logical bitstream must appear first; the +media mapping specifies the order of the initial pages. For example, +Ogg A/V will eventually specify an OggSquish video bitstream with +audio. The mapping may specify that the physical bitstream must begin +with the initial page of a logical video bitstream, followed by the +initial page of an audio stream. Unlike initial pages, terminal pages +for the logical bitstreams need not all occur contiguously (although a +specific media mapping may require this; it is not mandated by the +generic OggSquish stream spec). Terminal pages may be 'nil' pages, +that is, pages containing no content but simply a page header with +position information and the 'last page of bitstream' flag set in the +page header.

+ +Each grouped bitstream must have a unique serial number within the +scope of the physical bitstream.

+ +

sequential and concurrent multiplexing

+ +Groups of concurrently multiplexed bitstreams may be chained +consecutively. Such a physical bitstream obeys all the rules of both +grouped and chained multiplexed streams; the groups, when unchained , +must stand on their own as a valid concurrently multiplexed +bitstream.

+ +

multiplexing example

+ +Below, we present an example of a grouped and chained bitstream:

+ +

+ +In this example, we see pages from five total logical bitstreams +multiplexed into a physical bitstream. Note the following +characteristics: + +

  1. Grouped bitstreams begin together; all of the initial pages +must appear before any data pages. When concurrently multiplexed +groups are chained, the new group does not begin until all the +bitstreams in the previous group have terminated.

    + +

  2. The pages of concurrently multiplexed bitstreams need not conform +to a regular order; the only requirement is that page n of a +logical bitstream follow page n-1 in the physical bitstream. +There are no restrictions on intervening pages belonging to other +logical bitstreams. (Tying page appearence to bitrate demands is one +logical strategy, ie, the page appears at the chronological point +where decode requires more information). + +
+ +
+ + + + + +OggSquish is a Xiphophorus 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 About +Xiphophorus for details. +

+ +Ogg Vorbis is the first OggSquish audio CODEC. Anyone may +freely use and distribute the OggSquish and Vorbis specification, +whether in a private, public or corporate capacity. However, +Xiphophorus and the Ogg project (xiph.org) reserve the right to set +the Ogg/Vorbis specification and certify specification compliance.

+ +Xiphophorus's Vorbis software CODEC implementation (libvorbis and the +vorbis encode/decode/playback utility) are distributed under the GNU +Public License. This does not restrict third parties from +distributing independent implementations of Vorbis software under +other licenses.

+ +OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of +Xiphophorus. These pages are +copyright (C) 1994-1999 Xiphophorus. All rights reserved.

+ + + + diff --git a/doc/stream.gif b/doc/stream.gif new file mode 100644 index 0000000000000000000000000000000000000000..6cb7caee43fbd12654429d29042539e7104d9c1f GIT binary patch literal 3409 zcmbu6`6JVhpLaYzf|JBN?W(qYa-k{_So9*CX>kmfxz0@x~{HnX=y1UB4TD{ zhDxO}nM|=*Y;0^?Sy`E#o$cV@U~X<678b_ka-*Z8zkdDd<>i%-kWgD&+tbs-VzGom zp_!RkOiWBrP*8e$x~Hcnolf80iD(hp`B1U1Rsx1b-OrVf;u(e(WK|7KL`2Gtox2c= zrv^l=xCf592ab?zN-S)O4NV!U7?Q2~Wh~AYg|R@$Yarw`Rdtb%a@Cbi~k$#|2eE=mm57iLOU%w zIZE5X$;}hMZbLz`z*)fHf9C(a1V~F*04F;qH!r`S@Z9;L;*!!bE{|V+p`x;?`p=r$ zy84TPhQ>=x%`L5Mmxb*eS30j=>$=|EbE8+(*MIZY?K=Z^#e+ll?hlWQj*UN@DZAl1+0lm zV%US)Z3Zj1hLp7Sa$Ffdeu3iA+vKG3Zl>|bStps~Z9m}*vJ>qV}6a|geBbtcxTyGSD`d0q+UjI?Bf4cDiH zT{m%>s)@^scV*PIjQmNP;sG{94|_fF)K$@uZ}lgCB_>z475c^3{QL0-_*Q!Si5Hq1 zNz;q>eB7`#o&`$YcVquh@cs9D-S~y|i?RRo?MNi@y?c<>Wvd!lmE-t@ENbyHYWimI zd%>xX&7(_h%0@7H?EAQ=$Km=NG&sW0zD+wH9+FDWhV;T|th_sD+L^-KzJfpWaLmxy z{oWU_$&b?geezMxeaodknk5cR-1tW=94x*MxaeioShd&1dgRG6%Vemaw({(ws%Huw z`ka*u?bHCDibL3HD%Zvc)0C@r^D?h&emuP%aVOfVJnHV50)>gO()blbroK$@1V!DmL!>sFSQcVA4G>29tUdJc^v{yVGQq=przSR_@7H< zIQDu%=<6RL&BrjFuRzjB8UThOYk1c`^p{hP%Mv^(V1x?titDq`{5jYfoyCT!h11v~ zEAII>mt(4b)wU*=ocnz2dJ87ppV*V&D1*IEQ+Gw|6D(2T=(6Qgn4q%ec$)&f93%y5 z3`HUqQO0MpBzl|6N-p~vpvq1(xvJ63jop_Rq<>}#nxW7RC5RjoN1T{YeQ^@>@59Fw z$kKMk!QR=J44=V6(E>IMf;LF*U#!1nRGTqS6L9P2@cA~L%lQX!dmA^a~#ZQQJFP?)k9kATVo$jQdbu^SK`^ zL1cy)9>duXDP3^n`qnc4z!?Bsv^P-bt||95?n_S~(n|W~M2U@5w{j)*gDo@<)c`+= zw0*J5KL@12hD$?-kg9&rf~l#vtZ3VjdLWlzFc`0qGXylv{(uqlfmKNDpCWvlZah<9b19jr!QYBj?E<7k-~wg zZ;1=AZ{W6Q3g`f#R_{};EToNt>MVomd)nl9CvZkPS-HA$lx$Wky)y)UZ_kWa?zkQF z!AL3qN4Mt?}CRhg1B&c=dkC~)$x5{-8e|o!X%Hd z-e{8K;yyWY1rbH5U(3YzzbnMvWO~CLqN;*){x(OL8^p!epry7$yGrO-nE<9PD%lKX zIPV=6n9!``Pq;pWoHNp4v3G_07ev^8tFB54@SQp#8HjZ^tZ845^c$>xvL1Z3HumPY z%3U+RModxAkM@hYgJT{Xlj(~}zwpsR%;|?rA)W-c*~N=4Kz|U&!ZsomyDG2bMPA6% zE&Q-8u`#Hon+m_ZXmjg3a^!b)Y}2BS-XqtW-g$N9bi?9#MGdr%pWn#?S}Pp)^tHLV zPCFyN$x=t-M1Pu6|F__A8RC--_UoDe|IuvTIgpxrRSI0`K|8rcU94S zU60D%vQ7?DE^j+PvYnp0*YKWnuD)7U)i8PwJzcYglFuGxGDyz$7UOQb{nL0*uC zSS_Bjkhbd@zfP0r;-Z(6BLk8_wA74v{$6@gG9%NQtc&Vky{VHrRrSEwPQj0r$2zyA zU$7Tg)o~-+_m%=hVd5@=MfVhHDY^b|oz|UWtZ6gW@z!tEu#ncfi(RMFDn4C=MYggN zHr%5V_Vc zqN(WOcj2kGzxi#PdA7z_e2#~j(qIU94qVEHt>~()sG(|O9ZQtKxq=0J07lqHm-S7s zz00409WZ@^2n6iVQg$!yFHxk4tiRaE9M%ydkHdZv+!d2Dr_+`rpnLy1Lr+UJoJdqY zRH0aL@WAKt6I4on2c}M_*UfIqa`sn&p9-%xQ}MPb84gU`p1f>w$F7V9{rHOe*P30s z#fvo~I|?`o_EQZPgbh>wJfRHWTa>TS01|DjxZ(^?8cktT9Zv;2SL)9uEP?xfmqX6L zzqi?o3+D^vw!(`TqqikrL=Vp9_y~w8v5IlS9%BH zS&YR-u;$kkq&{U(hNqPz<0vW3YAyZ!_E~D*mIuorj;qM|D(+Cg%Q}l~l~3;EgyhK` z2t{XK@;I8x|L1Q}bbet`#LHjfG%@exnw-voMFwxN1x(_jV8?s0)!BFxMIdmU8Rj%% zA;BXXjg@>Bx4K}5^&ISPyH_Q_@f+(_vSln~yyupR;>7d%LELK&sHP{t18@ALg6R8R z&4uV|wyJCQBO|Q=JYt#|mZm$3H=th6oVMLR{WG)4B*zTwOD`<+PU$AAdMLi z2FbyyB|mLdy=Z6nM**rR$-oY+ESr#)tA=Sc2WlM7n4iE%6Vu9C)6y!lDjK38f}|K@ z5SMhu+UtO06gU{-@7m_jIG-;BNSMDE8Zwq5Zh%-N zfbXa2mZ}v5dgZA9%p{Ge^6j!5>6SPG28m!*sqdwl_w9b+W z%HOArIjYPN&RT3j0({_;n}q_jrXtPq^M|5}H-N#VxCBQO1fC%cPf0QNK@`}^6I_Yj zwn|&-xiph.org: OggSquish Vorbis documentation + +

+ + +

+OggSquish Vorbis encoding format documentation +

+ +Last update to this document: July 15, 1999
+Last update to Vorbis documentation: July 15, 1999

+ +
+ + +As of writing, not all the below document +links are live. They will be populated as we complete the +documents. +
+ +

+

Documents

+ + +

Description

+Ogg Vorbis is a general purpose compressed audio format +for high quality (44.1-48.0kHz, 16+ bit, polyphonic) audio and music +at moderate fixed and variable bitrates (40-80 kb/s/channel). This +places Vorbis in the same class as audio representations including +MPEG-1 audio layer 3, MPEG-4 audio (AAC and TwinVQ), and PAC.

+ +Vorbis is the first of a planned family of OggSquish multimedia coding +formats being developed as part of Xiphophorus's OggSquish multimedia +project. See http://www.xiph.org/ +for more information. + +

Vorbis technical documents

+ +A Vorbis encoder takes in overlapping (but contiguous) short-time +segments of audio data. The encoder analyzes the content of the audio +to determine an optimal compact representation; this phase of encoding +is known as analysis. For each short-time block of sound, +the encoder then packs an efficient representation of the signal, as +determined by analysis, into a raw packet much smaller than the size +required by the original signal; this phase is coding. +Lastly, in a streaming environment, the raw packets are then +structured into a continuous stream of octets; this last phase is +streaming. Note that the stream of octets is referred to both +as a 'byte-' and 'bit-'stream; the latter usage is acceptible as the +stream of octets is a physical representation of a true logical +bit-by-bit stream.

+ +A Vorbis decoder performs a mirror image process of extracting the +original sequence of raw packets from an Ogg stream (stream +decomposition), reconstructing the signal representation from the +raw data in the packet (decoding) and them reconstituting an +audio signal from the decoded representation (synthesis).

+ +The Programming with libvorbis +documents discuss use of the reference Vorbis codec library +(libvorbis) produced by Xiphophorus.

+ +The data representations and algorithms necessary at each step to +encode and decode Ogg Vorbis bitstreams are described by the below +documents in sufficient detail to construct a complete Vorbis codec. +Note that at the time of writing, Vorbis is still in a 'Request For +Comments' stage of development; despite being in advanced stages of +development, input from the multimedia community is welcome.

+ +

Vorbis analysis and synthesis

+ +Analysis begins by seperating an input audio stream into individual, +overlapping short-time segments of audio data. These segments are +then transformed into an alternate representation, seeking to +represent the original signal in a more efficient form that codes into +a smaller number of bytes. The analysis and transformation stage is +the most complex element of producing a Vorbis bitstream.

+ +The corresponding synthesis step in the decoder is simpler; there is +no analysis to perform, merely a mechanical, deterministic +reconstruction of the original audio data from the transform-domain +representation.

+ +

    +
  • Vorbis packet structure: Describes the basic analysis components necessary to produce Vorbis packets and the structure of the packet itself. +
  • Temporal envelope shaping and blocksize: Use of temporal envelope shaping and variable blocksize to minimize time-domain energy leakage during wide dynamic range and spectral energy swings. Also discusses time-related principles of psychoacoustics. +
  • Time domain segmentation and MDCT transform: Division of time domain data into individual overlapped, windowed short-time vectors and transformation using the MDCT +
  • The resolution floor: Use of frequency doamin psychoacoustics, and the MDCT-domain noise, masking and resolution floors +
  • MDCT-domain fine structure: Production, quantization and massaging of MDCT-spectrum fine structure +
+ +

Vorbis coding and decoding

+ +Coding and decoding converts the transform-domain representation of +the original audio produced by analysis to and from a bitwise packed +raw data packet. Coding and decoding consist of two logically +orthogonal concepts, back-end coding and bitpacking.

+ +Back-end coding uses a probability model to represent the raw numbers +of the audio representation in as few physical bits as possible; +familiar examples of back-end coding include Huffman coding and Vector +Quantization.

+ +Bitpacking arranges the variable sized words of the back-end +coding into a vector of octets without wasting space. The octets +produced by coding a single short-time audio segment is one raw Vorbis +packet.

+ +

+ +

Vorbis streaming and stream decomposition

+ +Vorbis packets contain the raw, bitwise-compressed representation of a +snippet of audio. These packets contain no structure and cannot be +strung together directly into a stream; for streamed transmission and +storage, Vorbis packets are encoded into an Ogg bitstream.

+ +

    + +
  • OggSquish bitstream overview: High-level +description of OggSquish logical bitstreams, how logical bitstreams +(of mixed media types) can be combined into physical bitstreams, and +restrictions on logical-to-physical mapping. Note that this document is +not specific only to Ogg Vorbis. + +
  • OggSquish logical bitstream and framing +spec: Low level, complete specification of OggSquish logical +bitstream pages. Note that this document is not specific only to Ogg +Vorbis. + +
  • Vorbis bitstream mapping: +Specifically describes mapping Vorbis data into an +OggSquish physical bitstream. + +
+ + +
+ + + + + +OggSquish is a Xiphophorus 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 About +Xiphophorus for details. +

+ +Ogg Vorbis is the first OggSquish audio CODEC. Anyone may +freely use and distribute the OggSquish and Vorbis specification, +whether in a private, public or corporate capacity. However, +Xiphophorus and the Ogg project (xiph.org) reserve the right to set +the Ogg/Vorbis specification and certify specification compliance.

+ +Xiphophorus's Vorbis software CODEC implementation (libvorbis and the +vorbis encode/decode/playback utility) are distributed under the GNU +Public License. This does not restrict third parties from +distributing independent implementations of Vorbis software under +other licenses.

+ +OggSquish, Vorbis, Xiphophorus and their logos are trademarks (tm) of +Xiphophorus. These pages are +copyright (C) 1994-1999 Xiphophorus. All rights reserved.

+ + + + + + + + diff --git a/doc/vorbisword2.gif b/doc/vorbisword2.gif new file mode 100644 index 0000000000000000000000000000000000000000..204a7de2b547661b44ce13ebaaa0df5acda61c41 GIT binary patch literal 1464 zcmb8p30sl}007_*{QLwYCBiaB3Lba_Wv$H27NJ;{6j`aMTexA~jmjCCD?lwlQPM;W zBOuE&G;IyZ6w|Em&gPYs8J16(TI;k8xBY~@zu?^#;P16DvIk%S82|u>gJ<*edU|^` z*J^@;_sz^qS5#K^jCOT&w0nE|q^73W*%5v`#F;ToPfQqfy6X%76Uk)7jO0WSkH;p( z5Vr*|Spew^2txrFfCBvMzXf1!B0A-AVihq}nuOQQTuN_J;!~bxHf?r6ujFp0;PdX4 z9lf96eX*}1X~)&D+Tohy&Nrzo<8{2iRr21c>#5y`Z$6#VrtPYIH2b;fWbf?P1-?L- zo{@R_OqNKTog>N3lb+2lI9Hf&bru1kU`f_!r3zLowgk!na4iBvm4(4oN>u#?R)rRT zTpG)(Xjagb$~9IM$nc8|PLK-4f{+!K5LDYGFGoTMU$A)%qzyBmQRdFDo;_`rl!+O} z({_)J(F2J3$K>Bwu!^riX$=g{lhw905m9?KSY8kvQfa8yEXGSvd$H-ZNlSL(#JNgD zvnx>_c`Ki6dU3~Bpqw}>NwgJ?{-WknpyhjU(%5bWER3`>Ym-f11{`462UmAE3|Gh1 zvc;k2-)E$kVuaK??#35pxGhn?Qb}yS0D$ZW{JI7iA8TQNY>Di|&^+hU2aK6rubLuI zJ2BGaxMjj*M^A4radw#K4tToX=^5Wc1MW}v(tf!??o&E~X|l`wrG601+n44sx|~|# z!0>?h^oZ%o@}-!+LPDn!%za^E57z{kpjG=(o{jKsZ!z%ferA{RwI+}(UfA=b+UToxtMb{CB-W)CJW0b{EmL5U+T zr1N~DhBnOa$gv&Y>>B8Pu_#FR+1A|=K2K7lV~-F+tiLOWDX9;9QQ;~zsHczt&F^*} z;swQ)i_;X!Xk_F3GDom=@(Qhz#=5JoapDdk^He#7e=vtke9kVK+_n+U0I43zI)$N} zbD`9PIxJA{T8~}@5=PqcROr;9Ky<#yD0I$pp@*ydVx6y0AA81Wn`U-sG^Nlcx^8Kh zOn%d6Dtv(X)r&ixS+>Se{~Zl<)K}6A7iAQe{H* z&)5?Mp&opc;E3))0R4>IAtGF-hFCTXdi=)&Y?S{uqbb%1_WA~AoCpsO@tux8O#Kp1 za^H9){Cx|U&05(RNIn$H+i&+)Is7?ydF}3UH)7(V))KXFgk1AIxABOaR(x6Q-uIrx zwA>mg9Fwr$GD|^r<0RCjvz;tDXyOl<2=g^`5!p)_V$j{_MvtuOaLv8kbSrV(+Y9dY zMX>3$V@iBuFMK}Xo}$#SvQUL~iL^w|hrFx)eOhtU*DZQJP5DXsJjQOz$cb4iRpZ}1 ztZL~G&;6gJ5ZtfX$U7C{_+w*b*vSpMf}QQ6Ss%6-v+#q-r>x`On6iU=>K6MLlJ1`b zG4f#9ZN0vqvjnkk6uGWdf0;!F7E_4WrYkK^qVlNP*DH9GesH#19T(CNb_0J~Hjv|z z861x>ZJ#ppWPs*j4d&Nz`j(?UZ2mfeaF82RFfg6IzCn*~k=eA912qSS>PRtDFVSYj zWk3*zFF!xkj+vqCSof!^{em_NoSn0x{)E$`0=}iM)xDK)b1o5HZolh2`Zkx>b;<4% KA_D^eoBjbgW~oU4 literal 0 HcmV?d00001 diff --git a/doc/wait.gif b/doc/wait.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0da80f7f3a16e55f914904dc55e8375cd59fe0b GIT binary patch literal 359 zcmZ?wbhEHbRANwKc+9}?L&SlBfuW&=;m03_4Owc6x=<10~i#4vM_Qn@H6ND%>kOJ#K6Gv@54#Y>>UeVolO@wtdJ7Bla(b< zL^E?=hSai_-$jOk=ic^S-Yt9fS@n~qgNcDfE^5{LmVJ)gEz5gjjhJ=7v{@|7-P5!r zN@8DdN?1uacr-p#2nk-&?Cj`pUzUZn)+V$(r;dq*iG!V;qoc+n&aJIoiIanaQ(?kH zTX`eDdPOGAS&N(el^K~?gDVT_=gje2E52skqV=0rIBuPv;jy!;Z+Wn$^5g}Mi)wn# z?8$67c_6pHvZQ~{B%di&XJ@Q$3~{-0Dz9e7jQZlzOHv6*OFwa@W!%m-ivGoR@yU-X v>)zEaeB!cz)8_HC3WXc~iHfPbvUXe2-II2Tis~9QHv2s0^38Zp0r2494ciq-(vUdB&{RHL;0>$({p6=B}Bwf zBw8+vlJ&(+h5K-w(BopO*5z=OYU?6-aOsP?>yNnC@2}_ey!-?GJUpYFfedFVIy-?H2mu7U9>;$+L#1=hFO^J}$5|6vf** zfwRq`@Z@1>=$?0b7SrUrI@aH~rR-R^qA3XDzO_3f+BBsf+^E|C{%5RL$inE@I8H{w z;dqXJpil&?mmv%Q9N_q+{N)lLE8gV?0vs(*4PHziO5S{aR7JCCcW!<3#_ZAz;b!DU zk7QP5(@U4t&*oH@$hnejvMpZh59cKQ{1rKyk;h0qwj&wJLy&^P?1Lo;`BY#iRE&@a z5F24s3qskom24&jkFUDmQ_Mj41QnBcxt&8+^T{_zbqQ&jD=G>^xIhH=l!6{sRyB>r zVhxY@kXow|KO_S^wVArq{^svLY+a(=+)>&WMJ4r?{QaNfgt)uL z?^p9zxRmQC%OJU0g3F^wL&i0;b=`@S2au~+(V}a4IM-v`r``Z^nfu~qMngyg9lBdw zm1k0XXQKxuzcfQRor5PlQIs~>mFc>lOgCv;-P;~S{k-o*y_lBP-C}i{Lzf@jInw-c zzW5Cl$%U-h*(7E1?+LvZuZJ9*4Td)v@09K`x~i9jFYcV^JK}`qVDf;^ltb6vq@AOn zw-PT-v87jzb-W;*|5}+bk2R~I8B?APTTx|>@40iBX3ys)3Ks`-o80W(U)$GV7ySDd z=e4pp(ftOmLL2JIyOUYSr-~e$1+A*<Y>`1FQ&ynz4iB+a1vD`p4mv%|wcn=Sw z9V9{dFfKjBK~nqqm^YM3;Rb9B<{KA?$Yk4AdA#h=)w?j(DofNz4fo@q5jWlZz6*J! zollfuovkqnN(7)E)HYx5s3h5iDNWfGL z1xFnLh|ahEIL-_Au_geHAe^z-%hZR$vr9bh`_4fnhW2BeZ)OEXwz~CDtPip5AwA#R oa@-}UeV`9rN;Kti98ZfQ-AX?faf5#Bw|Mqj#LM>#9spbZ1q)o*l>h($ literal 0 HcmV?d00001 diff --git a/doc/white-xifish.gif b/doc/white-xifish.gif new file mode 100644 index 0000000000000000000000000000000000000000..e76d03680f32000a89f1f85e9031fec108bf546b GIT binary patch literal 943 zcmZ?wbhEHbG-5DfSjxb_%E`qvVFGhdaQ_4r9&Lkj=UF_xc$va#wF(p-@JhLQ2!QIn0fI;ym3nLeU0)q|%5P*Ei!1m8! zLV<^lRR4)3MV)&rW?aa)e6Yf6eSrGbuD5=&(d){2E;UJJ82-$%TYfb=?e^bo$EFrn z{hfE__4gXrx^#io{DPV~S$PgFhJG#dY>9GgOOo>0;5Z&(t)6Z?V8Mj5)Kd6&Sqv6wp~5BQ%k&usX>{~szf0`|BzmuXx_Us;*N=I)q)2MOWi^w43*EyF>>4taMWY9 z7I!n4V7z=Udq2yZC1PDC+I;6RF-V*&X!PHj#j8_cQ0i#RwC2~wEr%H!EIHkNGR?E8 zWW2pf^4UJ4tT#-|3@mc)%VHL6dAXI_=!0&9aZ~G}g>sU+7?PNc;{SZ{+GpKi1kkjZqER*NQw_8&YC z1TvUB7IQMWD6#jdi!2GgCv?`*yie=#kyNGNR*@nxmBj@Lu9MG2b~-37%K5Z_VUbFB z>Qph;gHIJRO_ZiZrqA2?L?U}rr`w#0Nypvi<~-9(SJ--UX50Kzj9M)7n}1oVFX$-i ze7>knX_oquHnyr0i>E3Drq7v@R`o)W@mm0FX}&D^yrcAc9b3xhQP DM#HTk literal 0 HcmV?d00001 diff --git a/lib/analysis.c b/lib/analysis.c index 9bc4fcd..dc31653 100644 --- a/lib/analysis.c +++ b/lib/analysis.c @@ -26,8 +26,6 @@ ********************************************************************/ -static const char rcsid[] = "$Id"; - #include /* pcm accumulator and multipliers @@ -307,3 +305,7 @@ int vorbis_analysis(vorbis_state *v, double **pcm, int vals){ /* done */ return(1); } + + + + diff --git a/lib/codec.h b/lib/codec.h index acfca40..a4c8f35 100644 --- a/lib/codec.h +++ b/lib/codec.h @@ -14,12 +14,10 @@ function: PCM data vector blocking, windowing and dis/reassembly author: Monty modifications by: Monty - last modification date: Jun 26 1999 + last modification date: Jul 13 1999 ********************************************************************/ -/* $Id: codec.h,v 1.2 1999/07/13 08:00:15 mwhitson Exp $ */ - #ifndef _vorbis_codec_h_ #define _vorbis_codec_h_ @@ -76,12 +74,22 @@ typedef struct { } vorbis_page; typedef struct { - unsigned size32 crc_lookup[256]; + + /* _________________________________________________ + body_data: |_________________________________________________| + body_returned ----^ ^ ^ ^ + body_processed------------' | | + body_fill ---------------------------------------' | + body_storage _______________________________________________' + + the header is labelled the same way. Not all the pointers are + used by both encode and decode */ unsigned char *body_data; /* bytes from packet bodies */ - long body_storage; - long body_fill; - long body_processed; + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + int *lacing_vals; /* The values that will go to the segment table */ size64 *pcm_vals; /* pcm_pos values for headers. Not compact @@ -89,9 +97,11 @@ typedef struct { lacing fifo */ long lacing_storage; long lacing_fill; + long lacing_packet; + long lacing_returned; - unsigned char header[282]; /* working space for header */ - int headerbytes; + unsigned char header[282]; /* working space for header encode */ + int header_fill; int e_o_s; /* set when we have buffered the last packet in the logical bitstream */ @@ -99,17 +109,31 @@ typedef struct { of a logical bitstream */ long serialno; long pageno; + size64 pcmpos; + } vorbis_stream_state; typedef struct { unsigned char *packet; long bytes; + long b_o_s; long e_o_s; size64 pcm_pos; } vorbis_packet; +typedef struct { + char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} vorbis_sync_state; + /* libvorbis encodes in two abstraction layers; first we perform DSP and produce a packet (see docs/analysis.txt). The packet is then coded into a framed bitstream by the second layer (see @@ -136,6 +160,14 @@ extern int vorbis_stream_clear(vorbis_stream_state *vs); extern int vorbis_stream_destroy(vorbis_stream_state *vs); extern int vorbis_stream_eof(vorbis_stream_state *vs); +extern int vorbis_page_version(vorbis_page *vg); +extern int vorbis_page_continued(vorbis_page *vg); +extern int vorbis_page_bos(vorbis_page *vg); +extern int vorbis_page_eos(vorbis_page *vg); +extern size64 vorbis_page_pcmpos(vorbis_page *vg); +extern int vorbis_page_serialno(vorbis_page *vg); +extern int vorbis_page_pageno(vorbis_page *vg); + /* ENCODING PRIMITIVES: packet streaming layer **********************/ extern int vorbis_stream_encode(vorbis_stream_state *vs,vorbis_packet *vp); @@ -143,22 +175,19 @@ extern int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg); /* DECODING PRIMITIVES: packet streaming layer **********************/ -/* returns nonzero when it has a complete vorbis packet synced and - framed for decoding. Generally, it wants to see two page headers at - proper spacing before returning 'yea'. An exception is the initial - header to make IDing the vorbis stream easier: it will return sync - on the page header + beginning-of-stream marker. +extern int vorbis_sync_init(vorbis_sync_state *vs); +extern int vorbis_sync_clear(vorbis_sync_state *vs); +extern int vorbis_sync_destroy(vorbis_sync_state *vs); - _sync will also abort framing if is sees a problem in the packet - boundary lacing. */ - -extern int vorbis_stream_decode(vorbis_stream_state *vs,char *stream,int size); -extern int vorbis_stream_sync(vorbis_stream_state *vs); -extern int vorbis_stream_verify(vorbis_stream_state *vs); -extern size64 vorbis_stream_position(vorbis_stream_state *vs); -extern int vorbis_stream_skippage(vorbis_stream_state *vs); +extern char *vorbis_decode_buffer(vorbis_sync_state *vs, long size); +extern int vorbis_decode_wrote(vorbis_sync_state *vs, long bytes); +extern int vorbis_decode_stream(vorbis_sync_state *vs, vorbis_page *vg); +extern int vorbis_decode_page(vorbis_stream_state *vs, vorbis_page *vg); extern int vorbis_stream_packet(vorbis_stream_state *vs,vorbis_packet *vp); +extern int vorbis_sync_reset(vorbis_sync_state *vs); +extern int vorbis_stream_reset(vorbis_stream_state *vs); + /* DECODING PRIMITIVES: synthesis layer *****************************/ extern int vorbis_synthesis_info(vorbis_dsp_state *vd,vorbis_info *vi); diff --git a/lib/envelope.c b/lib/envelope.c index 601f6cf..71efd4b 100644 --- a/lib/envelope.c +++ b/lib/envelope.c @@ -22,8 +22,6 @@ ********************************************************************/ -static const char rcsid[] = "$Id"; - #include #include #include diff --git a/lib/framing.c b/lib/framing.c index 3f35a77..1a9fdb1 100644 --- a/lib/framing.c +++ b/lib/framing.c @@ -6,7 +6,7 @@ * PLEASE READ THESE TERMS DISTRIBUTING. * * * * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 * - * by 1999 Monty and The XIPHOPHORUS Company * + * by 1999 Monty and the XIPHOPHORUS Company * * http://www.xiph.org/ * * * ******************************************************************** @@ -15,7 +15,7 @@ decode vorbis streams back into raw packets author: Monty modifications by: Monty - last modification date: Jul 10 1999 + last modification date: Jul 13 1999 note: The CRC code is directly derived from public domain code by Ross Williams (ross@guest.adelaide.edu.au). See framing.txt for @@ -23,15 +23,60 @@ ********************************************************************/ -static const char rcsid[] = "$Id"; - #include #include #include "codec.h" /* A complete description of Vorbis framing exists in docs/framing.txt */ +int vorbis_page_version(vorbis_page *vg){ + return((int)(vg->header[4])); +} + +int vorbis_page_continued(vorbis_page *vg){ + return((int)(vg->header[5]&0x01)); +} + +int vorbis_page_bos(vorbis_page *vg){ + return((int)(vg->header[5]&0x02)); +} + +int vorbis_page_eos(vorbis_page *vg){ + return((int)(vg->header[5]&0x04)); +} + +size64 vorbis_page_pcmpos(vorbis_page *vg){ + char *page=vg->header; + size64 pcmpos=page[13]; + pcmpos= (pcmpos<<8)|page[12]; + pcmpos= (pcmpos<<8)|page[11]; + pcmpos= (pcmpos<<8)|page[10]; + pcmpos= (pcmpos<<8)|page[9]; + pcmpos= (pcmpos<<8)|page[8]; + pcmpos= (pcmpos<<8)|page[7]; + pcmpos= (pcmpos<<8)|page[6]; + return(pcmpos); +} + +int vorbis_page_serialno(vorbis_page *vg){ + return(vg->header[14] | + (vg->header[15]<<8) | + (vg->header[16]<<16) | + (vg->header[17]<<24)); +} + +int vorbis_page_pageno(vorbis_page *vg){ + return(vg->header[18] | + (vg->header[19]<<8) | + (vg->header[20]<<16) | + (vg->header[21]<<24)); +} + /* helper to initialize lookup for direct-table CRC */ + +static unsigned size32 crc_lookup[256]; +static int crc_ready=0; + static unsigned size32 _vorbis_crc_entry(unsigned long index){ int i; unsigned long r; @@ -48,8 +93,22 @@ static unsigned size32 _vorbis_crc_entry(unsigned long index){ return (r & 0xffffffffUL); } +/* mind this in threaded code; sync_init and stream_init call it. + It's thread safe only after the first time it returns */ + +static void _vorbis_crc_init(void){ + if(!crc_ready){ + /* initialize the crc_lookup table */ + int i; + for (i=0;i<256;i++) + crc_lookup[i]=_vorbis_crc_entry((unsigned long)i); + crc_ready=0; + } +} + +/* init the encode/decode logical stream state */ + int vorbis_stream_init(vorbis_stream_state *vs,int serialno){ - int i; if(vs){ memset(vs,0,sizeof(vorbis_stream_state)); vs->body_storage=16*1024; @@ -59,9 +118,8 @@ int vorbis_stream_init(vorbis_stream_state *vs,int serialno){ vs->lacing_vals=malloc(vs->lacing_storage*sizeof(int)); vs->pcm_vals=malloc(vs->lacing_storage*sizeof(size64)); - /* initialize the crc_lookup table */ - for (i=0;i<256;i++) - vs->crc_lookup[i]=_vorbis_crc_entry((unsigned long)i); + /* initialize the crc_lookup table if not done */ + _vorbis_crc_init(); vs->serialno=serialno; @@ -93,19 +151,33 @@ int vorbis_stream_destroy(vorbis_stream_state *vs){ /* Helpers for vorbis_stream_encode; this keeps the structure and what's happening fairly clear */ +static void _vs_body_expand(vorbis_stream_state *vs,int needed){ + if(vs->body_storage<=vs->body_fill+needed){ + vs->body_storage+=(needed+1024); + vs->body_data=realloc(vs->body_data,vs->body_storage); + } +} + +static void _vs_lacing_expand(vorbis_stream_state *vs,int needed){ + if(vs->lacing_storage<=vs->lacing_fill+needed){ + vs->lacing_storage+=(needed+32); + vs->lacing_vals=realloc(vs->lacing_vals,vs->lacing_storage*sizeof(int)); + vs->pcm_vals=realloc(vs->pcm_vals,vs->lacing_storage*sizeof(size64)); + } +} + /* checksum the page */ /* Direct table CRC; note that this will be faster in the future if we perform the checksum silmultaneously with other copies */ -static void _vs_checksum(vorbis_stream_state *vs,vorbis_page *vg){ +static void _vs_checksum(vorbis_page *vg){ unsigned size32 crc_reg=0; - unsigned size32 *lookup=vs->crc_lookup; int i; for(i=0;iheader_len;i++) - crc_reg=(crc_reg<<8)^lookup[((crc_reg >> 24)&0xff)^vg->header[i]]; + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^vg->header[i]]; for(i=0;ibody_len;i++) - crc_reg=(crc_reg<<8)^lookup[((crc_reg >> 24)&0xff)^vg->body[i]]; + crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^vg->body[i]]; vg->header[22]=crc_reg&0xff; vg->header[23]=(crc_reg>>8)&0xff; @@ -118,15 +190,8 @@ int vorbis_stream_encode(vorbis_stream_state *vs,vorbis_packet *vp){ int lacing_vals=vp->bytes/255+1,i; /* make sure we have the buffer storage */ - if(vs->body_storage<=vs->body_fill+vp->bytes){ - vs->body_storage+=(vp->bytes+1024); - vs->body_data=realloc(vs->body_data,vs->body_storage); - } - if(vs->lacing_storage<=vs->lacing_fill+lacing_vals){ - vs->lacing_storage+=(lacing_vals+32); - vs->lacing_vals=realloc(vs->lacing_vals,vs->lacing_storage*sizeof(int)); - vs->pcm_vals=realloc(vs->pcm_vals,vs->lacing_storage*sizeof(size64)); - } + _vs_body_expand(vs,vp->bytes); + _vs_lacing_expand(vs,lacing_vals); /* Copy in the submitted packet. Yes, the copy is a waste; this is the liability of overly clean abstraction for the time being. It @@ -168,7 +233,7 @@ int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg){ vs->body_fill-=vs->body_returned; memmove(vs->body_data,vs->body_data+vs->body_returned, - vs->body_fill*sizeof(char)); + (vs->body_fill-vs->body_returned)*sizeof(char)); vs->body_returned=0; } @@ -178,12 +243,14 @@ int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg){ int vals=0,bytes=0; int maxvals=(vs->lacing_fill>255?255:vs->lacing_fill); long acc=0; + size64 pcm_pos=vs->pcm_vals[0]; /* construct a page */ /* decide how many segments to include */ for(vals=0;vals4096)break; acc+=vs->lacing_vals[vals]&0x0ff; + if((vs->lacing_vals[vals]&0x0ff)<255)pcm_pos=vs->pcm_vals[vals]; } /* construct the header in temp storage */ @@ -192,27 +259,20 @@ int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg){ /* stream structure version */ vs->header[4]=0x00; - if(vs->b_o_s==0){ - /* Ah, this is the first page */ - vs->header[5]=0x00; - }else{ - if(vs->lacing_vals[0]&0x100){ - /* The first packet segment is the beginning of a packet */ - vs->header[5]=0x01; - }else{ - vs->header[5]=0x02; - } - } + + vs->header[5]=0x00; + /* continued packet flag? */ + if((vs->lacing_vals[0]&0x100)==0)vs->header[5]|=0x01; + /* first page flag? */ + if(vs->b_o_s==0)vs->header[5]|=0x02; + /* last page flag? */ + if(vs->e_o_s && vs->lacing_fill==vals)vs->header[5]|=0x04; vs->b_o_s=1; /* 64 bits of PCM position */ - { - size64 pcm_pos=vs->pcm_vals[vals-1]; - - for(i=6;i<14;i++){ - vs->header[i]=(pcm_pos&0xff); - pcm_pos>>=8; - } + for(i=6;i<14;i++){ + vs->header[i]=(pcm_pos&0xff); + pcm_pos>>=8; } /* 32 bits of stream serial number */ @@ -254,13 +314,13 @@ int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg){ /* set pointers in the vorbis_page struct */ vg->header=vs->header; - vg->header_len=vs->headerbytes=vals+27; + vg->header_len=vs->header_fill=vals+27; vg->body=vs->body_data; vg->body_len=bytes; /* calculate the checksum */ - _vs_checksum(vs,vg); + _vs_checksum(vg); return(1); } @@ -275,36 +335,343 @@ int vorbis_stream_eof(vorbis_stream_state *vs){ /* DECODING PRIMITIVES: packet streaming layer **********************/ -/* Accepts data for decoding; syncs and frames the bitstream, then - decodes pages into packets. Works through errors and dropouts, - reporting holes/errors in the bitstream when the missing/corrupt - packet is requested by vorbis_stream_packet(). Call with size=-1 - for EOS */ +/* This has two layers to place more of the multi-serialno and paging + control in the application's hands. First, we expose a data buffer + using vorbis_decode_buffer(). The app either copies into the + buffer, or passes it directly to read(), etc. We then call + vorbis_decode_wrote() to tell how many bytes we just added. + + Pages are returned (pointers into the buffer in vorbis_sync_state) + by vorbis_decode_stream(). The page is then submitted to + vorbis_decode_page() along with the appropriate + vorbis_stream_state* (ie, matching serialno). We then get raw + packets out calling vorbis_stream_packet() with a + vorbis_stream_state. See the 'frame-prog.txt' docs for details and + example code. */ + +/* initialize the struct to a known state */ +int vorbis_sync_init(vorbis_sync_state *vs){ + if(vs){ + memset(vs,0,sizeof(vorbis_sync_state)); + _vorbis_crc_init(); + } + return(0); +} + +/* clear non-flat storage within */ +int vorbis_sync_clear(vorbis_sync_state *vs){ + if(vs){ + if(vs->data)free(vs->data); + vorbis_sync_init(vs); + } + return(0); +} + +char *vorbis_decode_buffer(vorbis_sync_state *vs, long size){ -/* all below: <0 error, 0 not enough data, >0 success */ + /* first, clear out any space that has been previously returned */ + if(vs->returned){ + vs->fill-=vs->returned; + if(vs->fill-vs->returned>0) + memmove(vs->data,vs->data+vs->returned, + (vs->fill-vs->returned)*sizeof(char)); + vs->returned=0; + } -int vorbis_stream_decode(vorbis_stream_state *vs,char *stream,int size){ - /* beginning a page? ie, no header started yet?*/ - if vs-> - - + if(size>vs->storage-vs->fill){ + /* We need to extend the internal buffer */ + long newsize=size+vs->fill+4096; /* an extra page to be nice */ + if(vs->data) + vs->data=realloc(vs->data,newsize); + else + vs->data=malloc(newsize); + vs->storage=newsize; + } + /* expose a segment at least as large as requested at the fill mark */ + return(vs->data+vs->fill); } -size64 vorbis_stream_pcmpos(vorbis_stream_state *vs){ +int vorbis_decode_wrote(vorbis_sync_state *vs, long bytes){ + if(vs->fill+bytes>vs->storage)return(-1); + vs->fill+=bytes; + return(0); +} + +/* sync the stream. If we had to recapture, return -1. If we + couldn't capture at all, return 0. If a page was already framed + and ready to go, return 1 and fill in the page struct. + + Returns pointers into buffered data; invalidated by next call to + _stream, _clear, _init, or _buffer */ + +int vorbis_decode_stream(vorbis_sync_state *vs, vorbis_page *vg){ + + /* all we need to do is verify a page at the head of the stream + buffer. If it doesn't verify, we look for the next potential + frame */ + + while(1){ + char *page=vs->data+vs->returned; + long bytes=vs->fill-vs->returned; + + if(vs->headerbytes==0){ + int headerbytes,i; + if(bytes<27)return(0); /* not enough for a header */ + + /* verify capture pattern */ + if(memcmp(page,"OggS",4))goto sync_fail; + + headerbytes=page[26]+27; + if(bytesbodybytes+=page[27+i]; + vs->headerbytes=headerbytes; + } + + if(vs->bodybytes+vs->headerbytes>bytes)return(0); + + /* The whole test page is buffered. Verify the checksum */ + { + /* Grab the checksum bytes, set the header field to zero */ + char chksum[4]; + vorbis_page lvg; + + memcpy(chksum,page+22,4); + memset(page+22,0,4); + + /* set up a temp page struct and recompute the checksum */ + lvg.header=page; + lvg.header_len=vs->headerbytes; + lvg.body=page+vs->headerbytes; + lvg.body_len=vs->bodybytes; + _vs_checksum(&lvg); + + /* Compare */ + if(memcmp(chksum,page+22,4)){ + /* D'oh. Mismatch! Corrupt page (or miscapture and not a page + at all) */ + /* replace the computed checksum with the one actually read in */ + memcpy(page+22,chksum,4); + + /* Bad checksum. Lose sync */ + goto sync_fail; + } + } + + vg->header=page; + vg->header_len=vs->headerbytes; + vg->body=page+vs->headerbytes; + vg->body_len=vs->bodybytes; + + vs->unsynced=0; + vs->returned+=vs->headerbytes+vs->bodybytes; + vs->headerbytes=0; + vs->bodybytes=0; + + return(1); + + sync_fail: + + vs->headerbytes=0; + vs->bodybytes=0; + + /* search for possible capture */ + + page=memchr(page+1,'O',bytes-1); + if(page) + vs->returned=page-vs->data; + else + vs->returned=vs->fill; + + if(!vs->unsynced){ + vs->unsynced=1; + return(-1); + } + + /* loop; verifier above will take care of determining capture or not */ + + } } -size64 vorbis_stream_pageno(vorbis_stream_state *vs){ +/* add the incoming page to the stream state; we decompose the page + into packet segments here as well. */ + +int vorbis_decode_page(vorbis_stream_state *vs, vorbis_page *vg){ + unsigned char *header=vg->header; + unsigned char *body=vg->body; + long bodysize=vg->body_len; + int segptr=0; + + int version=vorbis_page_version(vg); + int continued=vorbis_page_continued(vg); + int bos=vorbis_page_bos(vg); + int eos=vorbis_page_eos(vg); + size64 pcmpos=vorbis_page_pcmpos(vg); + int serialno=vorbis_page_serialno(vg); + int pageno=vorbis_page_pageno(vg); + int segments=header[26]; + + /* clean up 'returned data' */ + { + long lr=vs->lacing_returned; + long br=vs->body_returned; + + /* body data */ + if(vs->body_fill-br) + memmove(vs->body_data,vs->body_data+br,vs->body_fill-br); + vs->body_fill-=br; + vs->body_returned=0; + + /* segment table */ + if(vs->lacing_fill-lr){ + memmove(vs->lacing_vals,vs->lacing_vals+lr, + (vs->lacing_fill-lr)*sizeof(int)); + memmove(vs->pcm_vals,vs->pcm_vals+lr, + (vs->lacing_fill-lr)*sizeof(size64)); + } + vs->lacing_fill-=lr; + vs->lacing_packet-=lr; + vs->lacing_returned=0; + } + + /* check the serial number */ + if(serialno!=vs->serialno)return(-1); + if(version>0)return(-1); + + _vs_lacing_expand(vs,segments+1); + + /* are we in sequence? */ + if(pageno!=vs->pageno){ + int i; + + /* unroll previous partial packet (if any) */ + for(i=vs->lacing_packet;ilacing_fill;i++) + vs->body_fill-=vs->lacing_vals[i]&0xff; + vs->lacing_fill=vs->lacing_packet; + + /* make a note of dropped data in segment table */ + vs->lacing_vals[vs->lacing_fill++]=0x400; + vs->lacing_packet++; + + /* are we a 'continued packet' page? If so, we'll need to skip + some segments */ + if(continued){ + bos=0; + for(;segptrbody_data+vs->body_fill,body,bodysize); + vs->body_fill+=bodysize; + } + + while(segptrlacing_vals[vs->lacing_fill]=val; + vs->pcm_vals[vs->lacing_fill]=pcmpos; + + if(bos){ + vs->lacing_vals[vs->lacing_fill]|=0x100; + bos=0; + } + + vs->lacing_fill++; + segptr++; + + if(val<255)vs->lacing_packet=vs->lacing_fill; + } + if(eos){ + vs->e_o_s=1; + if(vs->lacing_fill>0) + vs->lacing_vals[vs->lacing_fill-1]|=0x200; + } + + vs->pageno=pageno; + + return(0); } -int vorbis_stream_skippage(vorbis_stream_state *vs){ +/* clear things to an initial state. Good to call, eg, before seeking */ +int vorbis_sync_reset(vorbis_sync_state *vs){ + vs->fill=0; + vs->returned=0; + vs->unsynced=0; + vs->headerbytes=0; + vs->bodybytes=0; + return(0); } -int vorbis_stream_clearbuf(vorbis_stream_state *vs){ +int vorbis_stream_reset(vorbis_stream_state *vs){ + vs->body_fill=0; + vs->body_returned=0; + + vs->lacing_fill=0; + vs->lacing_packet=0; + vs->lacing_returned=0; + + vs->header_fill=0; + + vs->e_o_s=0; + vs->b_o_s=0; + vs->pageno=0; + vs->pcmpos=0; + + return(0); } int vorbis_stream_packet(vorbis_stream_state *vs,vorbis_packet *vp){ + + /* The last part of decode. We have the stream broken into packet + segments. Now we need to group them into packets (or return the + out of sync markers) */ + + int ptr=vs->lacing_returned; + + if(vs->lacing_packet<=ptr)return(0); + if(vs->lacing_vals[ptr]&=0x400){ + /* We lost sync here; let the app know */ + vs->lacing_returned++; + return(-1); + } + + /* Gather the whole packet. We'll have no holes or a partial packet */ + { + int size=vs->lacing_vals[ptr]&0xff; + int bytes=0; + + vp->packet=vs->body_data+vs->body_returned; + vp->e_o_s=vs->lacing_vals[ptr]&0x200; /* last packet of the stream? */ + vp->b_o_s=vs->lacing_vals[ptr]&0x100; /* first packet of the stream? */ + bytes+=size; + + while(size==255){ + int val=vs->lacing_vals[++ptr]; + size=val&0xff; + if(val&0x200)vp->e_o_s=0x200; + bytes+=size; + } + vp->pcm_pos=vs->pcm_vals[ptr]; + vp->bytes=bytes; + + vs->body_returned+=bytes; + vs->lacing_returned=ptr+1; + } + return(1); } #ifdef _V_SELFTEST @@ -642,3 +1009,7 @@ int main(void){ } #endif + + + + diff --git a/lib/mdct.c b/lib/mdct.c index f6fd63b..f28fb4e 100644 --- a/lib/mdct.c +++ b/lib/mdct.c @@ -36,8 +36,6 @@ ********************************************************************/ -static const char rcsid[] = "$Id"; - #include #include #include @@ -338,3 +336,16 @@ void iMDCT(double *in, double *out, MDCT_lookup *init, double *window){ } } } + + + + + + + + + + + + + diff --git a/lib/mdct.h b/lib/mdct.h index 526187b..f7d3dbd 100644 --- a/lib/mdct.h +++ b/lib/mdct.h @@ -15,8 +15,6 @@ ********************************************************************/ -/* $Id: mdct.h,v 1.2 1999/07/13 08:00:19 mwhitson Exp $ */ - #ifndef _OGG_MDCT_H_ #define _OGG_MDCT_H_ -- 2.7.4