Ogg Vorbis decoder

This page has been superseded. The current location of the project is in the stb header-file library github repository.

Sponsorship

RAD Game Tools sponsored the development of this software with the understanding I would place it in the public domain.

Source code

Ogg Vorbis decoder: C source file

Limitations

API

The API for using the library is documented in the source code, specifically in the "header file" section of the file. Generally, there are three ways to give it data:

Generally, there are three ways to get data from it:

Sample Code & Data

This directory includes some sample code, sample.c, which demonstrates a number of variations of the API.

Also provided are several test ogg files at varying levels of compression.

Compilation

stb_vorbis is provided as a single .C file. You can extract the header file from it and use it in several possible ways.

If you don't want to use stdio or one of the pushdata or pulldata apis, there are particular #defines you can define globally to disable them; see the source code.

You can also suppress all usage of the C runtime library, but you will need to provide replacement functions and #defines, documented below.

  1. If you want to use it "normally"
  2. If you want to use it wrapped (only one file will call it)
  3. Using it without using the CRT
You can also avoid having to cut-and-paste the header file with new releases by doing the following:
  1. create 'stb_vorbis.h'
  2. #define STB_VORBIS_HEADER_ONLY
  3. #include "stb_vorbis.c"
Most new releases don't change the header file (except to add new items to it), the same as any other library system, so this shouldn't be necessary in general, but if you like the feeling of security from it, go for it.

C Runtime Library usage

If you use STB_VORBIS_NO_CRT, you'll need to provide a wrapper file with definitions like the following:
#define STB_VORBIS_NO_CRT
#define assert(x)      // or MyAssert(x)

#define malloc       my_allocator
#define free         my_deallocator
#define pow          my_pow
#define floor        my_floor

#ifdef ALWAYS_USE_STB_VORBIS_ALLOC
#define alloca(a)    0  // and don't use the alloca() path!
#else  // use malloc/free instead of alloca
#define alloca(a)    malloc(a)  // this is actually the macro above
#define dealloca(p)  free(p)    // this is actually the macro above
#endif


void memset(void *base, int val, int len)
{
   int i;
   for (i=0; i < len; ++i) ((char *) base)[i] = val;
}

int memcmp(void *p1, void *p2, int len)
{
   unsigned char *q1 = (unsigned char *) p1;
   unsigned char *q2 = (unsigned char *) p2;
   int i;
   for (i=0; i < len; ++i)
      if (q1[i] < q2[i]) return -1;
      else if (q1[i] > q2[i]) return 1;
   return 0;
}

void memcpy(void *dest, void *src, int num)
{
   int i;
   for (i=0; i < num; ++i)
      ((char *)dest)[i] = ((char *) src)[i];
}

float
ldexp(float Value, int Exponent)
{
    return((float)((double)Value * pow(2.0, (double)Exponent)));
}

void qsort (void *base, unsigned num, unsigned width,
            int (*comp)(const void *, const void *))
{
...
}

#include "stb_vorbis.c"

You may have issues with the compiler generating float-to-int conversions (e.g. in MSVC, _ftol). You can avoid this by defining your floor() macro to call a float-to-int function; all float-to-int conversions in stb_vorbis.c are (supposed to be) wrapped in a call to floor() for this reason.

Internals documentation

These documents may be of use in people trying to modify the source code.

vorbis_codebook.txt
Implementation of regular and sparse codebooks
vorbis_input.txt
How input is processed, especially pushdata versus normal

Public Domain "license"

I, Sean Barrett, single-handedly wrote the decoder, and as the legal author (it was not a "work for hire") placed it in the public domain in April, 2007. That means I have disclaimed copyright of it. You can take the source code and use it for any purpose, commercial or non-commercial, copyrighted, open-source, Free, free, or public domain, with no legal obligation to acknowledge the borrowing/copying in any way.

Commentary:

The difference between public domain and, say, a Creative Commons commercial / non-share-alike / attribution license is solely the requirement for attribution. (Similarly the BSD license and such.) While I would appreciate acknowledgement and attribution, I believe that it is foolish to place a legal encumberment (i.e. a license) on the software solely to get attribution.

For example, consider that actual person-hours must have been invested in making sure this page properly covered all Valve's legal issues with regards to attribution-required software. (Information needed to propogate from the programmers who incorporated the libraries to whoever maintains that web page.) Those person-hours cost the company actual money, despite the fact that nobody is ever going to look at this or care.

In other words, I'm arguing that PD is superior to the BSD license and the Creative Commons 'Attribution' license. If the license offers anything besides attribution -- as does, e.g., CC NonCommercial-ShareAlike, or the GPL -- that's an entirely different story.

Bugs

There are almost certainly bugs in the current version. I welcome reports of bugs (especially with accompanying .ogg files that exhibit the bugs), and will be happy to attempt to fix bugs and provide updated versions. My email address is 'sean' care of this domain name.

No Warranty

This software is in the public domain. You are not entering into a contract with me or anyone else when you use this software. It is a gift. As such, various laws regarding warranties express or implied do not apply in any way. Nevertheless, in case there is any doubt, I do not offer you any warranty, express or implied, for its behavior, nor fitness of purpose towards any application. If it manages to decode some Ogg Vorbis streams for you, count yourself lucky.

Version History

Clean Room implementation

It is my intent that this implementation does not infringe the copyrights or other intellectual property of anyone. In particular, I did not look at the source code to the Ogg Vorbis reference implementation by Xiph.org. The implementation was primarily created from the Ogg and Vorbis specifications available on the Xiph.org website, and related documents linked by them. Documents referenced in the log above:
ogg spec:
http://xiph.org/vorbis/doc/framing.html
http://xiph.org/vorbis/doc/oggstream.html
vorbis spec:
http://xiph.org/vorbis/doc/Vorbis_I_spec.html
Sporer et al:
The use of multirate filter banks for coding of high quality digital audio, Th.Sporer, Kh.Brandenburg, B.Edler. (Note that there are errors in the fast-IMDCT implementation in this paper, even the corrected version.)
wikipedia MDCT:
http://en.wikipedia.org/wiki/Modified_discrete_cosine_transform

Additionally, I did some further optimization of the MDCT from the original code, after I stopped keeping the log. This optimization process roughly doubled the speed of the MDCT. The following files show how the old version was optimized step by step from the naive 'as written by Sporer et al'.

Versions startings at mdct_11.txt exhibit some error due to a bug in the unrolling of 'step 2' which was fixed in version 0.9994.

Reference data

The Vorbis specification involves the creation of a large quantity of "intermediate state" that is then transformed (by the IMDCT) into final output. When the final output of my algorithm was wrong due to bugs in my code, it would have been extremely difficult to work backwards and decipher where it was going wrong. Instead, I had a friend generate reference data with the intermediate state defined by the specification. This data was generated from the Xiph reference implementation; however, all the generated data is defined by the specification, and beyond this data there was no information transferred to me about the Xiph implementation.
test1.ogg
One of the test files used to generate the reference data; this is what I sent out.
test1.log (170 KB)
The output reference data for the test.ogg file. (This consists of the symbols decoded for codebooks, and the various floor, residue, coupled residue, spectral envelope, and post-IMDCT buffers.) This is what I received.
tests.7z (23 MB)
The data dump files output containing the reference data for all five test ogg files (I cannot provide the other ogg files for copyright reasons). This is the entirety of what I received.
muratorigo.log
muratorigo.xml
The log of the IM conversation I had instructing my friend in what I wanted him to output to the reference files. This was our entire conversation about Ogg Vorbis, so you can verify that no information about the code or its structure leaked from him to me in the course of this effort. (These files were created by the IM client Trillian. I do not know why muratorigo.log contains binary characters.)