Ogg Vorbis decoder

Sponsorship

Source code

Limitations

Currently no true seeking API

Can only contain one Vorbis stream (not multiple independent streams concatenated)

Does not support lossless deletion of samples from the front

Does not implement "floor 0", which is apparently used by some old Vorbis files

Hand it a block of memory with the entire Ogg Vorbis stream

Hand if a FILE * (or a filename) from which it will stream

Hand it blocks of data at a time that you get from any source you like

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

Ask it for the entire file decoded into an interleaved 16-bit buffer malloc()ed by the library

Ask it for (an internal, unpredictably-sized) frame at a time, in floats or 16-bit ints

Ask it for N samples at a time, in floats or 16-bits

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

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.

If you want to use it "normally" cut-and-paste the 'header file' section out into a header file

compile stb_vorbis.c as is If you want to use it wrapped (only one file will call it) create a wrapper C/C++ file

#include "stb_vorbis.c"

write your wrappers right there (note, you have to avoid namespace conflicts with statics in stb_vorbis.c)

no header file is needed Using it without using the CRT cut-and-paste the 'header file' section into a header file

make a wrapper C/C++ file

#define STB_VORBIS_NO_CRT

create #defines or static functions implementing everything needed (see below)

#include "stb_vorbis.c"

create 'stb_vorbis.h' #define STB_VORBIS_HEADER_ONLY #include "stb_vorbis.c"

C Runtime Library usage

#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

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

No Warranty

0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila

0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem

0.99994 - change fast-float-to-int to work in single-precision FPU mode, remove endian-dependence

0.99993 - remove assert that fired on legal files with empty tables

0.99992 - rewind-to-start

0.99991 - bugfix to stb_vorbis_get_samples_short by Bernhard Wodo

0.9999 - (should have been 0.99990) fix no-CRT support, compiling as C++

0.9998 - add a full-decode function with a memory source

0.9997 - fix a bug in the read-from-FILE case in 0.9996 addition

0.9996 - query length of vorbis stream in samples/seconds

0.9995 - bugfix to another optimization that only happened in certain files

0.9994 - bugfix to one of the optimizations that caused significant (but inaudible?) errors

0.9993 - performance improvements; runs in 99% to 104% of time of reference implementation

0.9992 - performance improvement of IMDCT; now performs close to reference implementation

0.9991 - performance improvement of IMDCT

0.999 - (should have been 0.9990) performance improvement of IMDCT

0.998 - no-CRT support from Casey Muratori

0.997 - bugfixes for bugs found by Terje Mathisen

0.996 - bugfix: fast-huffman decode initialized incorrectly for sparse codebooks; fixing gives 10% speedup - found by Terje Mathisen

0.995 - bugfix: fix to 'effective' overrun detection - found by Terje Mathisen

0.994 - bugfix: garbage decode on final VQ symbol of a non-multiple - found by Terje Mathisen

0.993 - bugfix: pushdata API required 1 extra byte for empty page (failed to consume final page if empty) - found by Terje Mathisen

0.992 - fixes for MinGW warning

0.991 - turn fast-float-conversion on by default

0.990 - fix push-mode seek recovery if you seek into the headers

0.98b - fix to bad release of 0.98

0.98 - fix push-mode seek recovery; robustify float-to-int and support non-fast mode

0.97 - builds under c++ (typecasting, don't use 'class' keyword)

0.96 - somehow MY 0.95 was right, but the web one was wrong, so here's my 0.95 rereleased as 0.96, fixes a typo in the clamping code

0.95 - clamping code for 16-bit functions

0.94 - not publically released

0.93 - fixed all-zero-floor case (was decoding garbage)

0.92 - fixed a memory leak

0.91 - conditional compiles to omit parts of the API and the infrastructure to support them: STB_VORBIS_NO_PULLDATA_API , STB_VORBIS_NO_PUSHDATA_API , STB_VORBIS_NO_STDIO , STB_VORBIS_NO_INTEGER_CONVERSION

, , , 0.90 - first public release

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'.

mdct_01.txt - original naive implementation using original variable names

mdct_02.txt - v. 0.90: "optimized" to use only one temporary buffer

mdct_03.txt - v. 0.999: de-sparsify from using only odd slots; bitreverse in table; skip initial mirroring step

mdct_04.txt - (inner loop only) optimizing the inner loop of step 3 by making index calculations explicit

mdct_05.txt - (comments only) notes on optimizing all but the last iteration of step 3

mdct_06.txt - after splitting off the first iteration, and making a separate case with r nested inside s instead of vice versa, and after doing heavy unrolling/pointer-walk optimizations (I didn't save the intermediate step before optimizing)

mdct_07.txt - fairly small change: pulling out floating-point add sub-expressions (e.g. X+Y is used twice)

mdct_08.txt - v. 0.9991: making most steps in-place; combining steps 5+6+7

mdct_09.txt - (todo description of diffs)

mdct_10.txt - (todo description of diffs)

mdct_11.txt - (todo description of diffs)

mdct_12.txt - (todo description of diffs)

mdct_13.txt - v. 0.9992: (todo description of diffs)

Reference data