/src/middleware/stb_vorbis/stb_vorbis.c
https://bitbucket.org/vivkin/gam3b00bs/ · C · 5143 lines · 3973 code · 572 blank · 598 comment · 1013 complexity · 2048a9cd8e2bddc7e14a8b87072fc020 MD5 · raw file
Large files are truncated click here to view the full file
- #include "stb_vorbis.h"
-
- #ifndef STB_VORBIS_HEADER_ONLY
-
- // global configuration settings (e.g. set these in the project/makefile),
- // or just set them in this file at the top (although ideally the first few
- // should be visible when the header file is compiled too, although it's not
- // crucial)
-
- // STB_VORBIS_NO_PUSHDATA_API
- // does not compile the code for the various stb_vorbis_*_pushdata()
- // functions
- // #define STB_VORBIS_NO_PUSHDATA_API
-
- // STB_VORBIS_NO_PULLDATA_API
- // does not compile the code for the non-pushdata APIs
- // #define STB_VORBIS_NO_PULLDATA_API
-
- // STB_VORBIS_NO_STDIO
- // does not compile the code for the APIs that use FILE *s internally
- // or externally (implied by STB_VORBIS_NO_PULLDATA_API)
- // #define STB_VORBIS_NO_STDIO
-
- // STB_VORBIS_NO_INTEGER_CONVERSION
- // does not compile the code for converting audio sample data from
- // float to integer (implied by STB_VORBIS_NO_PULLDATA_API)
- // #define STB_VORBIS_NO_INTEGER_CONVERSION
-
- // STB_VORBIS_NO_FAST_SCALED_FLOAT
- // does not use a fast float-to-int trick to accelerate float-to-int on
- // most platforms which requires endianness be defined correctly.
- //#define STB_VORBIS_NO_FAST_SCALED_FLOAT
-
-
- // STB_VORBIS_MAX_CHANNELS [number]
- // globally define this to the maximum number of channels you need.
- // The spec does not put a restriction on channels except that
- // the count is stored in a byte, so 255 is the hard limit.
- // Reducing this saves about 16 bytes per value, so using 16 saves
- // (255-16)*16 or around 4KB. Plus anything other memory usage
- // I forgot to account for. Can probably go as low as 8 (7.1 audio),
- // 6 (5.1 audio), or 2 (stereo only).
- #ifndef STB_VORBIS_MAX_CHANNELS
- #define STB_VORBIS_MAX_CHANNELS 16 // enough for anyone?
- #endif
-
- // STB_VORBIS_PUSHDATA_CRC_COUNT [number]
- // after a flush_pushdata(), stb_vorbis begins scanning for the
- // next valid page, without backtracking. when it finds something
- // that looks like a page, it streams through it and verifies its
- // CRC32. Should that validation fail, it keeps scanning. But it's
- // possible that _while_ streaming through to check the CRC32 of
- // one candidate page, it sees another candidate page. This #define
- // determines how many "overlapping" candidate pages it can search
- // at once. Note that "real" pages are typically ~4KB to ~8KB, whereas
- // garbage pages could be as big as 64KB, but probably average ~16KB.
- // So don't hose ourselves by scanning an apparent 64KB page and
- // missing a ton of real ones in the interim; so minimum of 2
- #ifndef STB_VORBIS_PUSHDATA_CRC_COUNT
- #define STB_VORBIS_PUSHDATA_CRC_COUNT 4
- #endif
-
- // STB_VORBIS_FAST_HUFFMAN_LENGTH [number]
- // sets the log size of the huffman-acceleration table. Maximum
- // supported value is 24. with larger numbers, more decodings are O(1),
- // but the table size is larger so worse cache missing, so you'll have
- // to probe (and try multiple ogg vorbis files) to find the sweet spot.
- #ifndef STB_VORBIS_FAST_HUFFMAN_LENGTH
- #define STB_VORBIS_FAST_HUFFMAN_LENGTH 10
- #endif
-
- // STB_VORBIS_FAST_BINARY_LENGTH [number]
- // sets the log size of the binary-search acceleration table. this
- // is used in similar fashion to the fast-huffman size to set initial
- // parameters for the binary search
-
- // STB_VORBIS_FAST_HUFFMAN_INT
- // The fast huffman tables are much more efficient if they can be
- // stored as 16-bit results instead of 32-bit results. This restricts
- // the codebooks to having only 65535 possible outcomes, though.
- // (At least, accelerated by the huffman table.)
- #ifndef STB_VORBIS_FAST_HUFFMAN_INT
- #define STB_VORBIS_FAST_HUFFMAN_SHORT
- #endif
-
- // STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
- // If the 'fast huffman' search doesn't succeed, then stb_vorbis falls
- // back on binary searching for the correct one. This requires storing
- // extra tables with the huffman codes in sorted order. Defining this
- // symbol trades off space for speed by forcing a linear search in the
- // non-fast case, except for "sparse" codebooks.
- // #define STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
-
- // STB_VORBIS_DIVIDES_IN_RESIDUE
- // stb_vorbis precomputes the result of the scalar residue decoding
- // that would otherwise require a divide per chunk. you can trade off
- // space for time by defining this symbol.
- // #define STB_VORBIS_DIVIDES_IN_RESIDUE
-
- // STB_VORBIS_DIVIDES_IN_CODEBOOK
- // vorbis VQ codebooks can be encoded two ways: with every case explicitly
- // stored, or with all elements being chosen from a small range of values,
- // and all values possible in all elements. By default, stb_vorbis expands
- // this latter kind out to look like the former kind for ease of decoding,
- // because otherwise an integer divide-per-vector-element is required to
- // unpack the index. If you define STB_VORBIS_DIVIDES_IN_CODEBOOK, you can
- // trade off storage for speed.
- //#define STB_VORBIS_DIVIDES_IN_CODEBOOK
-
- // STB_VORBIS_CODEBOOK_SHORTS
- // The vorbis file format encodes VQ codebook floats as ax+b where a and
- // b are floating point per-codebook constants, and x is a 16-bit int.
- // Normally, stb_vorbis decodes them to floats rather than leaving them
- // as 16-bit ints and computing ax+b while decoding. This is a speed/space
- // tradeoff; you can save space by defining this flag.
- #ifndef STB_VORBIS_CODEBOOK_SHORTS
- #define STB_VORBIS_CODEBOOK_FLOATS
- #endif
-
- // STB_VORBIS_DIVIDE_TABLE
- // this replaces small integer divides in the floor decode loop with
- // table lookups. made less than 1% difference, so disabled by default.
-
- // STB_VORBIS_NO_INLINE_DECODE
- // disables the inlining of the scalar codebook fast-huffman decode.
- // might save a little codespace; useful for debugging
- // #define STB_VORBIS_NO_INLINE_DECODE
-
- // STB_VORBIS_NO_DEFER_FLOOR
- // Normally we only decode the floor without synthesizing the actual
- // full curve. We can instead synthesize the curve immediately. This
- // requires more memory and is very likely slower, so I don't think
- // you'd ever want to do it except for debugging.
- // #define STB_VORBIS_NO_DEFER_FLOOR
-
-
-
-
- //////////////////////////////////////////////////////////////////////////////
-
- #ifdef STB_VORBIS_NO_PULLDATA_API
- #define STB_VORBIS_NO_INTEGER_CONVERSION
- #define STB_VORBIS_NO_STDIO
- #endif
-
- #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
- #define STB_VORBIS_NO_STDIO 1
- #endif
-
- #ifndef STB_VORBIS_NO_INTEGER_CONVERSION
- #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT
-
- // only need endianness for fast-float-to-int, which we don't
- // use for pushdata
-
- #ifndef STB_VORBIS_BIG_ENDIAN
- #define STB_VORBIS_ENDIAN 0
- #else
- #define STB_VORBIS_ENDIAN 1
- #endif
-
- #endif
- #endif
-
-
- #ifndef STB_VORBIS_NO_STDIO
- #include <stdio.h>
- #endif
-
- #ifndef STB_VORBIS_NO_CRT
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <math.h>
- #include <malloc.h>
- #else
- #define NULL 0
- #endif
-
- #ifndef _MSC_VER
- #if __GNUC__
- #define __forceinline inline
- #else
- #define __forceinline
- #endif
- #endif
-
- #if STB_VORBIS_MAX_CHANNELS > 256
- #error "Value of STB_VORBIS_MAX_CHANNELS outside of allowed range"
- #endif
-
- #if STB_VORBIS_FAST_HUFFMAN_LENGTH > 24
- #error "Value of STB_VORBIS_FAST_HUFFMAN_LENGTH outside of allowed range"
- #endif
-
-
- #define MAX_BLOCKSIZE_LOG 13 // from specification
- #define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG)
-
-
- typedef unsigned char uint8;
- typedef signed char int8;
- typedef unsigned short uint16;
- typedef signed short int16;
- typedef unsigned int uint32;
- typedef signed int int32;
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- #ifdef STB_VORBIS_CODEBOOK_FLOATS
- typedef float codetype;
- #else
- typedef uint16 codetype;
- #endif
-
- // @NOTE
- //
- // Some arrays below are tagged "//varies", which means it's actually
- // a variable-sized piece of data, but rather than malloc I assume it's
- // small enough it's better to just allocate it all together with the
- // main thing
- //
- // Most of the variables are specified with the smallest size I could pack
- // them into. It might give better performance to make them all full-sized
- // integers. It should be safe to freely rearrange the structures or change
- // the sizes larger--nothing relies on silently truncating etc., nor the
- // order of variables.
-
- #define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH)
- #define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1)
-
- typedef struct
- {
- int dimensions, entries;
- uint8 *codeword_lengths;
- float minimum_value;
- float delta_value;
- uint8 value_bits;
- uint8 lookup_type;
- uint8 sequence_p;
- uint8 sparse;
- uint32 lookup_values;
- codetype *multiplicands;
- uint32 *codewords;
- #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT
- int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE];
- #else
- int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE];
- #endif
- uint32 *sorted_codewords;
- int *sorted_values;
- int sorted_entries;
- } Codebook;
-
- typedef struct
- {
- uint8 order;
- uint16 rate;
- uint16 bark_map_size;
- uint8 amplitude_bits;
- uint8 amplitude_offset;
- uint8 number_of_books;
- uint8 book_list[16]; // varies
- } Floor0;
-
- typedef struct
- {
- uint8 partitions;
- uint8 partition_class_list[32]; // varies
- uint8 class_dimensions[16]; // varies
- uint8 class_subclasses[16]; // varies
- uint8 class_masterbooks[16]; // varies
- int16 subclass_books[16][8]; // varies
- uint16 Xlist[31*8+2]; // varies
- uint8 sorted_order[31*8+2];
- uint8 neighbors[31*8+2][2];
- uint8 floor1_multiplier;
- uint8 rangebits;
- int values;
- } Floor1;
-
- typedef union
- {
- Floor0 floor0;
- Floor1 floor1;
- } Floor;
-
- typedef struct
- {
- uint32 begin, end;
- uint32 part_size;
- uint8 classifications;
- uint8 classbook;
- uint8 **classdata;
- int16 (*residue_books)[8];
- } Residue;
-
- typedef struct
- {
- uint8 magnitude;
- uint8 angle;
- uint8 mux;
- } MappingChannel;
-
- typedef struct
- {
- uint16 coupling_steps;
- MappingChannel *chan;
- uint8 submaps;
- uint8 submap_floor[15]; // varies
- uint8 submap_residue[15]; // varies
- } Mapping;
-
- typedef struct
- {
- uint8 blockflag;
- uint8 mapping;
- uint16 windowtype;
- uint16 transformtype;
- } Mode;
-
- typedef struct
- {
- uint32 goal_crc; // expected crc if match
- int bytes_left; // bytes left in packet
- uint32 crc_so_far; // running crc
- int bytes_done; // bytes processed in _current_ chunk
- uint32 sample_loc; // granule pos encoded in page
- } CRCscan;
-
- typedef struct
- {
- uint32 page_start, page_end;
- uint32 after_previous_page_start;
- uint32 first_decoded_sample;
- uint32 last_decoded_sample;
- } ProbedPage;
-
- struct stb_vorbis
- {
- // user-accessible info
- unsigned int sample_rate;
- int channels;
-
- unsigned int setup_memory_required;
- unsigned int temp_memory_required;
- unsigned int setup_temp_memory_required;
-
- // input config
- #ifndef STB_VORBIS_NO_STDIO
- FILE *f;
- uint32 f_start;
- int close_on_free;
- #endif
- #ifdef STB_VORBIS_USE_CALLBACKS
- STREAM_DATA_CLLBACK data_callback;
- STREAM_RESET_CLLBACK reset_callback;
- void* user_data;
- uint32 cb_offset;
- #endif
-
- uint8 *stream;
- uint8 *stream_start;
- uint8 *stream_end;
-
- uint32 stream_len;
-
- uint8 push_mode;
-
- uint32 first_audio_page_offset;
-
- ProbedPage p_first, p_last;
-
- // memory management
- stb_vorbis_alloc alloc;
- int setup_offset;
- int temp_offset;
-
- // run-time results
- int eof;
- enum STBVorbisError error;
-
- // user-useful data
-
- // header info
- int blocksize[2];
- int blocksize_0, blocksize_1;
- int codebook_count;
- Codebook *codebooks;
- int floor_count;
- uint16 floor_types[64]; // varies
- Floor *floor_config;
- int residue_count;
- uint16 residue_types[64]; // varies
- Residue *residue_config;
- int mapping_count;
- Mapping *mapping;
- int mode_count;
- Mode mode_config[64]; // varies
-
- uint32 total_samples;
-
- // decode buffer
- float *channel_buffers[STB_VORBIS_MAX_CHANNELS];
- float *outputs [STB_VORBIS_MAX_CHANNELS];
-
- float *previous_window[STB_VORBIS_MAX_CHANNELS];
- int previous_length;
-
- #ifndef STB_VORBIS_NO_DEFER_FLOOR
- int16 *finalY[STB_VORBIS_MAX_CHANNELS];
- #else
- float *floor_buffers[STB_VORBIS_MAX_CHANNELS];
- #endif
-
- uint32 current_loc; // sample location of next frame to decode
- int current_loc_valid;
-
- // per-blocksize precomputed data
-
- // twiddle factors
- float *A[2],*B[2],*C[2];
- float *window[2];
- uint16 *bit_reverse[2];
-
- // current page/packet/segment streaming info
- uint32 serial; // stream serial number for verification
- int last_page;
- int segment_count;
- uint8 segments[255];
- uint8 page_flag;
- uint8 bytes_in_seg;
- uint8 first_decode;
- int next_seg;
- int last_seg; // flag that we're on the last segment
- int last_seg_which; // what was the segment number of the last seg?
- uint32 acc;
- int valid_bits;
- int packet_bytes;
- int end_seg_with_known_loc;
- uint32 known_loc_for_packet;
- int discard_samples_deferred;
- uint32 samples_output;
-
- // push mode scanning
- int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching
- #ifndef STB_VORBIS_NO_PUSHDATA_API
- CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT];
- #endif
-
- // sample-access
- int channel_buffer_start;
- int channel_buffer_end;
- };
-
- extern int my_prof(int slot);
- //#define stb_prof my_prof
-
- #ifndef stb_prof
- #define stb_prof(x) 0
- #endif
-
- #if defined(STB_VORBIS_NO_PUSHDATA_API)
- #define IS_PUSH_MODE(f) FALSE
- #elif defined(STB_VORBIS_NO_PULLDATA_API)
- #define IS_PUSH_MODE(f) TRUE
- #else
- #define IS_PUSH_MODE(f) ((f)->push_mode)
- #endif
-
- typedef struct stb_vorbis vorb;
-
- static int error(vorb *f, enum STBVorbisError e)
- {
- f->error = e;
- if (!f->eof && e != VORBIS_need_more_data) {
- f->error=e; // breakpoint for debugging
- }
- return 0;
- }
-
-
- // these functions are used for allocating temporary memory
- // while decoding. if you can afford the stack space, use
- // alloca(); otherwise, provide a temp buffer and it will
- // allocate out of those.
-
- #define array_size_required(count,size) (count*(sizeof(void *)+(size)))
-
- #define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size))
- #ifdef dealloca
- #define temp_free(f,p) (f->alloc.alloc_buffer ? 0 : dealloca(size))
- #else
- #define temp_free(f,p) 0
- #endif
- #define temp_alloc_save(f) ((f)->temp_offset)
- #define temp_alloc_restore(f,p) ((f)->temp_offset = (p))
-
- #define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size)
-
- // given a sufficiently large block of memory, make an array of pointers to subblocks of it
- static void *make_block_array(void *mem, int count, int size)
- {
- int i;
- void ** p = (void **) mem;
- char *q = (char *) (p + count);
- for (i=0; i < count; ++i) {
- p[i] = q;
- q += size;
- }
- return p;
- }
-
- static void *setup_malloc(vorb *f, int sz)
- {
- sz = (sz+3) & ~3;
- f->setup_memory_required += sz;
- if (f->alloc.alloc_buffer) {
- void *p = (char *) f->alloc.alloc_buffer + f->setup_offset;
- if (f->setup_offset + sz > f->temp_offset) return NULL;
- f->setup_offset += sz;
- return p;
- }
- return sz ? malloc(sz) : NULL;
- }
-
- static void setup_free(vorb *f, void *p)
- {
- if (f->alloc.alloc_buffer) return; // do nothing; setup mem is not a stack
- free(p);
- }
-
- static void *setup_temp_malloc(vorb *f, int sz)
- {
- sz = (sz+3) & ~3;
- if (f->alloc.alloc_buffer) {
- if (f->temp_offset - sz < f->setup_offset) return NULL;
- f->temp_offset -= sz;
- return (char *) f->alloc.alloc_buffer + f->temp_offset;
- }
- return malloc(sz);
- }
-
- static void setup_temp_free(vorb *f, void *p, size_t sz)
- {
- if (f->alloc.alloc_buffer) {
- f->temp_offset += (sz+3)&~3;
- return;
- }
- free(p);
- }
-
- #define CRC32_POLY 0x04c11db7 // from spec
-
- static uint32 crc_table[256];
- static void crc32_init(void)
- {
- int i,j;
- uint32 s;
- for(i=0; i < 256; i++) {
- for (s=i<<24, j=0; j < 8; ++j)
- s = (s << 1) ^ (s >= (1<<31) ? CRC32_POLY : 0);
- crc_table[i] = s;
- }
- }
-
- static __forceinline uint32 crc32_update(uint32 crc, uint8 byte)
- {
- return (crc << 8) ^ crc_table[byte ^ (crc >> 24)];
- }
-
-
- // used in setup, and for huffman that doesn't go fast path
- static unsigned int bit_reverse(unsigned int n)
- {
- n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1);
- n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2);
- n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4);
- n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8);
- return (n >> 16) | (n << 16);
- }
-
- static float square(float x)
- {
- return x*x;
- }
-
- // this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3
- // as required by the specification. fast(?) implementation from stb.h
- // @OPTIMIZE: called multiple times per-packet with "constants"; move to setup
- static int ilog(int32 n)
- {
- static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };
-
- // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
- if (n < (1U << 14))
- if (n < (1U << 4)) return 0 + log2_4[n ];
- else if (n < (1U << 9)) return 5 + log2_4[n >> 5];
- else return 10 + log2_4[n >> 10];
- else if (n < (1U << 24))
- if (n < (1U << 19)) return 15 + log2_4[n >> 15];
- else return 20 + log2_4[n >> 20];
- else if (n < (1U << 29)) return 25 + log2_4[n >> 25];
- else if (n < (1U << 31)) return 30 + log2_4[n >> 30];
- else return 0; // signed n returns 0
- }
-
- #ifndef M_PI
- #define M_PI 3.14159265358979323846264f // from CRC
- #endif
-
- // code length assigned to a value with no huffman encoding
- #define NO_CODE 255
-
- /////////////////////// LEAF SETUP FUNCTIONS //////////////////////////
- //
- // these functions are only called at setup, and only a few times
- // per file
-
- static float float32_unpack(uint32 x)
- {
- // from the specification
- uint32 mantissa = x & 0x1fffff;
- uint32 sign = x & 0x80000000;
- uint32 exp = (x & 0x7fe00000) >> 21;
- double res = sign ? -(double)mantissa : (double)mantissa;
- return (float) ldexp((float)res, exp-788);
- }
-
-
- // zlib & jpeg huffman tables assume that the output symbols
- // can either be arbitrarily arranged, or have monotonically
- // increasing frequencies--they rely on the lengths being sorted;
- // this makes for a very simple generation algorithm.
- // vorbis allows a huffman table with non-sorted lengths. This
- // requires a more sophisticated construction, since symbols in
- // order do not map to huffman codes "in order".
- static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values)
- {
- if (!c->sparse) {
- c->codewords [symbol] = huff_code;
- } else {
- c->codewords [count] = huff_code;
- c->codeword_lengths[count] = len;
- values [count] = symbol;
- }
- }
-
- static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
- {
- int i,k,m=0;
- uint32 available[32];
-
- memset(available, 0, sizeof(available));
- // find the first entry
- for (k=0; k < n; ++k) if (len[k] < NO_CODE) break;
- if (k == n) { assert(c->sorted_entries == 0); return TRUE; }
- // add to the list
- add_entry(c, 0, k, m++, len[k], values);
- // add all available leaves
- for (i=1; i <= len[k]; ++i)
- available[i] = 1 << (32-i);
- // note that the above code treats the first case specially,
- // but it's really the same as the following code, so they
- // could probably be combined (except the initial code is 0,
- // and I use 0 in available[] to mean 'empty')
- for (i=k+1; i < n; ++i) {
- uint32 res;
- int z = len[i], y;
- if (z == NO_CODE) continue;
- // find lowest available leaf (should always be earliest,
- // which is what the specification calls for)
- // note that this property, and the fact we can never have
- // more than one free leaf at a given level, isn't totally
- // trivial to prove, but it seems true and the assert never
- // fires, so!
- while (z > 0 && !available[z]) --z;
- if (z == 0) { assert(0); return FALSE; }
- res = available[z];
- available[z] = 0;
- add_entry(c, bit_reverse(res), i, m++, len[i], values);
- // propogate availability up the tree
- if (z != len[i]) {
- for (y=len[i]; y > z; --y) {
- assert(available[y] == 0);
- available[y] = res + (1 << (32-y));
- }
- }
- }
- return TRUE;
- }
-
- // accelerated huffman table allows fast O(1) match of all symbols
- // of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH
- static void compute_accelerated_huffman(Codebook *c)
- {
- int i, len;
- for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i)
- c->fast_huffman[i] = -1;
-
- len = c->sparse ? c->sorted_entries : c->entries;
- #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT
- if (len > 32767) len = 32767; // largest possible value we can encode!
- #endif
- for (i=0; i < len; ++i) {
- if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) {
- uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i];
- // set table entries for all bit combinations in the higher bits
- while (z < FAST_HUFFMAN_TABLE_SIZE) {
- c->fast_huffman[z] = i;
- z += 1 << c->codeword_lengths[i];
- }
- }
- }
- }
-
- static int uint32_compare(const void *p, const void *q)
- {
- uint32 x = * (uint32 *) p;
- uint32 y = * (uint32 *) q;
- return x < y ? -1 : x > y;
- }
-
- static int include_in_sort(Codebook *c, uint8 len)
- {
- if (c->sparse) { assert(len != NO_CODE); return TRUE; }
- if (len == NO_CODE) return FALSE;
- if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE;
- return FALSE;
- }
-
- // if the fast table above doesn't work, we want to binary
- // search them... need to reverse the bits
- static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values)
- {
- int i, len;
- // build a list of all the entries
- // OPTIMIZATION: don't include the short ones, since they'll be caught by FAST_HUFFMAN.
- // this is kind of a frivolous optimization--I don't see any performance improvement,
- // but it's like 4 extra lines of code, so.
- if (!c->sparse) {
- int k = 0;
- for (i=0; i < c->entries; ++i)
- if (include_in_sort(c, lengths[i]))
- c->sorted_codewords[k++] = bit_reverse(c->codewords[i]);
- assert(k == c->sorted_entries);
- } else {
- for (i=0; i < c->sorted_entries; ++i)
- c->sorted_codewords[i] = bit_reverse(c->codewords[i]);
- }
-
- qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare);
- c->sorted_codewords[c->sorted_entries] = 0xffffffff;
-
- len = c->sparse ? c->sorted_entries : c->entries;
- // now we need to indicate how they correspond; we could either
- // #1: sort a different data structure that says who they correspond to
- // #2: for each sorted entry, search the original list to find who corresponds
- // #3: for each original entry, find the sorted entry
- // #1 requires extra storage, #2 is slow, #3 can use binary search!
- for (i=0; i < len; ++i) {
- int huff_len = c->sparse ? lengths[values[i]] : lengths[i];
- if (include_in_sort(c,huff_len)) {
- uint32 code = bit_reverse(c->codewords[i]);
- int x=0, n=c->sorted_entries;
- while (n > 1) {
- // invariant: sc[x] <= code < sc[x+n]
- int m = x + (n >> 1);
- if (c->sorted_codewords[m] <= code) {
- x = m;
- n -= (n>>1);
- } else {
- n >>= 1;
- }
- }
- assert(c->sorted_codewords[x] == code);
- if (c->sparse) {
- c->sorted_values[x] = values[i];
- c->codeword_lengths[x] = huff_len;
- } else {
- c->sorted_values[x] = i;
- }
- }
- }
- }
-
- // only run while parsing the header (3 times)
- static int vorbis_validate(uint8 *data)
- {
- static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' };
- return memcmp(data, vorbis, 6) == 0;
- }
-
- // called from setup only, once per code book
- // (formula implied by specification)
- static int lookup1_values(int entries, int dim)
- {
- int r = (int) floor(exp((float) log((float) entries) / dim));
- if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning;
- ++r; // floor() to avoid _ftol() when non-CRT
- assert(pow((float) r+1, dim) > entries);
- assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above
- return r;
- }
-
- // called twice per file
- static void compute_twiddle_factors(int n, float *A, float *B, float *C)
- {
- int n4 = n >> 2, n8 = n >> 3;
- int k,k2;
-
- for (k=k2=0; k < n4; ++k,k2+=2) {
- A[k2 ] = (float) cos(4*k*M_PI/n);
- A[k2+1] = (float) -sin(4*k*M_PI/n);
- B[k2 ] = (float) cos((k2+1)*M_PI/n/2) * 0.5f;
- B[k2+1] = (float) sin((k2+1)*M_PI/n/2) * 0.5f;
- }
- for (k=k2=0; k < n8; ++k,k2+=2) {
- C[k2 ] = (float) cos(2*(k2+1)*M_PI/n);
- C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n);
- }
- }
-
- static void compute_window(int n, float *window)
- {
- int n2 = n >> 1, i;
- for (i=0; i < n2; ++i)
- window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI)));
- }
-
- static void compute_bitreverse(int n, uint16 *rev)
- {
- int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions
- int i, n8 = n >> 3;
- for (i=0; i < n8; ++i)
- rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2;
- }
-
- static int init_blocksize(vorb *f, int b, int n)
- {
- int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3;
- f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2);
- f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2);
- f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4);
- if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem);
- compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]);
- f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2);
- if (!f->window[b]) return error(f, VORBIS_outofmem);
- compute_window(n, f->window[b]);
- f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8);
- if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem);
- compute_bitreverse(n, f->bit_reverse[b]);
- return TRUE;
- }
-
- static void neighbors(uint16 *x, int n, int *plow, int *phigh)
- {
- int low = -1;
- int high = 65536;
- int i;
- for (i=0; i < n; ++i) {
- if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; }
- if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; }
- }
- }
-
- // this has been repurposed so y is now the original index instead of y
- typedef struct
- {
- uint16 x,y;
- } Point;
-
- int point_compare(const void *p, const void *q)
- {
- Point *a = (Point *) p;
- Point *b = (Point *) q;
- return a->x < b->x ? -1 : a->x > b->x;
- }
-
- //
- /////////////////////// END LEAF SETUP FUNCTIONS //////////////////////////
-
-
- #if defined(STB_VORBIS_NO_STDIO)
- #define USE_MEMORY(z) TRUE
- #else
- #define USE_MEMORY(z) ((z)->stream)
- #endif
- #ifdef STB_VORBIS_USE_CALLBACKS
-
- #define USE_CALLBACKS(z) ((z)->data_callback)
-
- int stb_read_from_callback(vorb* z, int size, uint8* ptr)
- {
- int read = z->data_callback(size,ptr,z->user_data);
- if(read < 1 && size > 0)
- z->eof = 1;
- else
- z->cb_offset+=read;
- return read;
- }
-
- int stb_reset_callback(vorb* z)
- {
- int result = z->reset_callback(z->user_data);
- if(result == -1)
- z->eof = 1;
- else
- {
- z->cb_offset = 0;
- z->eof = 0;
- }
- return result;
- }
-
- #endif
-
- static uint8 get8(vorb *z)
- {
- if (USE_MEMORY(z)) {
- if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; }
- return *z->stream++;
- }
-
- #ifdef STB_VORBIS_USE_CALLBACKS
- if(USE_CALLBACKS(z))
- {
- uint8 data;
- int read = stb_read_from_callback(z,1,&data);
- if(z->eof)
- return 0;
- else
- return data;
- }
- #endif
-
- #ifndef STB_VORBIS_NO_STDIO
- {
- int c = fgetc(z->f);
- if (c == EOF) { z->eof = TRUE; return 0; }
- return c;
- }
- #endif
- }
-
- static uint32 get32(vorb *f)
- {
- uint32 x;
- x = get8(f);
- x += get8(f) << 8;
- x += get8(f) << 16;
- x += get8(f) << 24;
- return x;
- }
-
- static int getn(vorb *z, uint8 *data, int n)
- {
- if (USE_MEMORY(z)) {
- if (z->stream+n > z->stream_end) { z->eof = 1; return 0; }
- memcpy(data, z->stream, n);
- z->stream += n;
- return 1;
- }
-
- #ifdef STB_VORBIS_USE_CALLBACKS
- if(USE_CALLBACKS(z))
- {
- int read = stb_read_from_callback(z,n,data);
- if(read < n)
- {
- z->eof = 1;
- return 0;
- }
- else
- return 1;
- }
- #endif
-
- #ifndef STB_VORBIS_NO_STDIO
- if (fread(data, n, 1, z->f) == 1)
- return 1;
- else {
- z->eof = 1;
- return 0;
- }
- #endif
- }
-
- static void skip(vorb *z, int n)
- {
- if (USE_MEMORY(z)) {
- z->stream += n;
- if (z->stream >= z->stream_end) z->eof = 1;
- return;
- }
- #ifdef STB_VORBIS_USE_CALLBACKS
- if(USE_CALLBACKS(z))
- {
- int read = stb_read_from_callback(z,n,NULL);
- if(read < n)
- z->eof = 1;
- return;
- }
- #endif
-
-
- #ifndef STB_VORBIS_NO_STDIO
- {
- long x = ftell(z->f);
- fseek(z->f, x+n, SEEK_SET);
- }
- #endif
- }
-
- static int set_file_offset(stb_vorbis *f, unsigned int loc)
- {
- #ifndef STB_VORBIS_NO_PUSHDATA_API
- if (f->push_mode) return 0;
- #endif
- f->eof = 0;
- if (USE_MEMORY(f)) {
- if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) {
- f->stream = f->stream_end;
- f->eof = 1;
- return 0;
- } else {
- f->stream = f->stream_start + loc;
- return 1;
- }
- }
-
- #ifdef STB_VORBIS_USE_CALLBACKS
- if(USE_CALLBACKS(f))
- {
- int read = stb_reset_callback(f);
- if(read < 0)
- {
- f->eof = 1;
- return 0;
- }
- read = stb_read_from_callback(f,loc,NULL);
- if(read < loc)
- {
- f->eof = 1;
- return 0;
- }
- return 1;
- }
- #endif
-
- #ifndef STB_VORBIS_NO_STDIO
- if (loc + f->f_start < loc || loc >= 0x80000000) {
- loc = 0x7fffffff;
- f->eof = 1;
- } else {
- loc += f->f_start;
- }
- if (!fseek(f->f, loc, SEEK_SET))
- return 1;
- f->eof = 1;
- fseek(f->f, f->f_start, SEEK_END);
- return 0;
- #endif
- }
-
-
- static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 };
-
- static int capture_pattern(vorb *f)
- {
- if (0x4f != get8(f)) return FALSE;
- if (0x67 != get8(f)) return FALSE;
- if (0x67 != get8(f)) return FALSE;
- if (0x53 != get8(f)) return FALSE;
- return TRUE;
- }
-
- #define PAGEFLAG_continued_packet 1
- #define PAGEFLAG_first_page 2
- #define PAGEFLAG_last_page 4
-
- static int start_page_no_capturepattern(vorb *f)
- {
- uint32 loc0,loc1,n,i;
- // stream structure version
- if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version);
- // header flag
- f->page_flag = get8(f);
- // absolute granule position
- loc0 = get32(f);
- loc1 = get32(f);
- // @TODO: validate loc0,loc1 as valid positions?
- // stream serial number -- vorbis doesn't interleave, so discard
- get32(f);
- //if (f->serial != get32(f)) return error(f, VORBIS_incorrect_stream_serial_number);
- // page sequence number
- n = get32(f);
- f->last_page = n;
- // CRC32
- get32(f);
- // page_segments
- f->segment_count = get8(f);
- if (!getn(f, f->segments, f->segment_count))
- return error(f, VORBIS_unexpected_eof);
- // assume we _don't_ know any the sample position of any segments
- f->end_seg_with_known_loc = -2;
- if (loc0 != ~0 || loc1 != ~0) {
- // determine which packet is the last one that will complete
- for (i=f->segment_count-1; i >= 0; --i)
- if (f->segments[i] < 255)
- break;
- // 'i' is now the index of the _last_ segment of a packet that ends
- if (i >= 0) {
- f->end_seg_with_known_loc = i;
- f->known_loc_for_packet = loc0;
- }
- }
- if (f->first_decode) {
- int i,len;
- ProbedPage p;
- len = 0;
- for (i=0; i < f->segment_count; ++i)
- len += f->segments[i];
- len += 27 + f->segment_count;
- p.page_start = f->first_audio_page_offset;
- p.page_end = p.page_start + len;
- p.after_previous_page_start = p.page_start;
- p.first_decoded_sample = 0;
- p.last_decoded_sample = loc0;
- f->p_first = p;
- }
- f->next_seg = 0;
- return TRUE;
- }
-
- static int start_page(vorb *f)
- {
- if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern);
- return start_page_no_capturepattern(f);
- }
-
- static int start_packet(vorb *f)
- {
- while (f->next_seg == -1) {
- if (!start_page(f)) return FALSE;
- if (f->page_flag & PAGEFLAG_continued_packet)
- return error(f, VORBIS_continued_packet_flag_invalid);
- }
- f->last_seg = FALSE;
- f->valid_bits = 0;
- f->packet_bytes = 0;
- f->bytes_in_seg = 0;
- // f->next_seg is now valid
- return TRUE;
- }
-
- static int maybe_start_packet(vorb *f)
- {
- if (f->next_seg == -1) {
- int x = get8(f);
- if (f->eof) return FALSE; // EOF at page boundary is not an error!
- if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern);
- if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
- if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
- if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern);
- if (!start_page_no_capturepattern(f)) return FALSE;
- if (f->page_flag & PAGEFLAG_continued_packet) {
- // set up enough state that we can read this packet if we want,
- // e.g. during recovery
- f->last_seg = FALSE;
- f->bytes_in_seg = 0;
- return error(f, VORBIS_continued_packet_flag_invalid);
- }
- }
- return start_packet(f);
- }
-
- static int next_segment(vorb *f)
- {
- int len;
- if (f->last_seg) return 0;
- if (f->next_seg == -1) {
- f->last_seg_which = f->segment_count-1; // in case start_page fails
- if (!start_page(f)) { f->last_seg = 1; return 0; }
- if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid);
- }
- len = f->segments[f->next_seg++];
- if (len < 255) {
- f->last_seg = TRUE;
- f->last_seg_which = f->next_seg-1;
- }
- if (f->next_seg >= f->segment_count)
- f->next_seg = -1;
- assert(f->bytes_in_seg == 0);
- f->bytes_in_seg = len;
- return len;
- }
-
- #define EOP (-1)
- #define INVALID_BITS (-1)
-
- static int get8_packet_raw(vorb *f)
- {
- if (!f->bytes_in_seg)
- if (f->last_seg) return EOP;
- else if (!next_segment(f)) return EOP;
- assert(f->bytes_in_seg > 0);
- --f->bytes_in_seg;
- ++f->packet_bytes;
- return get8(f);
- }
-
- static int get8_packet(vorb *f)
- {
- int x = get8_packet_raw(f);
- f->valid_bits = 0;
- return x;
- }
-
- static void flush_packet(vorb *f)
- {
- while (get8_packet_raw(f) != EOP);
- }
-
- // @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important
- // as the huffman decoder?
- static uint32 get_bits(vorb *f, int n)
- {
- uint32 z;
-
- if (f->valid_bits < 0) return 0;
- if (f->valid_bits < n) {
- if (n > 24) {
- // the accumulator technique below would not work correctly in this case
- z = get_bits(f, 24);
- z += get_bits(f, n-24) << 24;
- return z;
- }
- if (f->valid_bits == 0) f->acc = 0;
- while (f->valid_bits < n) {
- int z = get8_packet_raw(f);
- if (z == EOP) {
- f->valid_bits = INVALID_BITS;
- return 0;
- }
- f->acc += z << f->valid_bits;
- f->valid_bits += 8;
- }
- }
- if (f->valid_bits < 0) return 0;
- z = f->acc & ((1 << n)-1);
- f->acc >>= n;
- f->valid_bits -= n;
- return z;
- }
-
- static int32 get_bits_signed(vorb *f, int n)
- {
- uint32 z = get_bits(f, n);
- if (z & (1 << (n-1)))
- z += ~((1 << n) - 1);
- return (int32) z;
- }
-
- // @OPTIMIZE: primary accumulator for huffman
- // expand the buffer to as many bits as possible without reading off end of packet
- // it might be nice to allow f->valid_bits and f->acc to be stored in registers,
- // e.g. cache them locally and decode locally
- static __forceinline void prep_huffman(vorb *f)
- {
- if (f->valid_bits <= 24) {
- if (f->valid_bits == 0) f->acc = 0;
- do {
- int z;
- if (f->last_seg && !f->bytes_in_seg) return;
- z = get8_packet_raw(f);
- if (z == EOP) return;
- f->acc += z << f->valid_bits;
- f->valid_bits += 8;
- } while (f->valid_bits <= 24);
- }
- }
-
- enum
- {
- VORBIS_packet_id = 1,
- VORBIS_packet_comment = 3,
- VORBIS_packet_setup = 5,
- };
-
- static int codebook_decode_scalar_raw(vorb *f, Codebook *c)
- {
- int i;
- prep_huffman(f);
-
- assert(c->sorted_codewords || c->codewords);
- // cases to use binary search: sorted_codewords && !c->codewords
- // sorted_codewords && c->entries > 8
- if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) {
- // binary search
- uint32 code = bit_reverse(f->acc);
- int x=0, n=c->sorted_entries, len;
-
- while (n > 1) {
- // invariant: sc[x] <= code < sc[x+n]
- int m = x + (n >> 1);
- if (c->sorted_codewords[m] <= code) {
- x = m;
- n -= (n>>1);
- } else {
- n >>= 1;
- }
- }
- // x is now the sorted index
- if (!c->sparse) x = c->sorted_values[x];
- // x is now sorted index if sparse, or symbol otherwise
- len = c->codeword_lengths[x];
- if (f->valid_bits >= len) {
- f->acc >>= len;
- f->valid_bits -= len;
- return x;
- }
-
- f->valid_bits = 0;
- return -1;
- }
-
- // if small, linear search
- assert(!c->sparse);
- for (i=0; i < c->entries; ++i) {
- if (c->codeword_lengths[i] == NO_CODE) continue;
- if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i])-1))) {
- if (f->valid_bits >= c->codeword_lengths[i]) {
- f->acc >>= c->codeword_lengths[i];
- f->valid_bits -= c->codeword_lengths[i];
- return i;
- }
- f->valid_bits = 0;
- return -1;
- }
- }
-
- error(f, VORBIS_invalid_stream);
- f->valid_bits = 0;
- return -1;
- }
-
- static int codebook_decode_scalar(vorb *f, Codebook *c)
- {
- int i;
- if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH)
- prep_huffman(f);
- // fast huffman table lookup
- i = f->acc & FAST_HUFFMAN_TABLE_MASK;
- i = c->fast_huffman[i];
- if (i >= 0) {
- f->acc >>= c->codeword_lengths[i];
- f->valid_bits -= c->codeword_lengths[i];
- if (f->valid_bits < 0) { f->valid_bits = 0; return -1; }
- return i;
- }
- return codebook_decode_scalar_raw(f,c);
- }
-
- #ifndef STB_VORBIS_NO_INLINE_DECODE
-
- #define DECODE_RAW(var, f,c) \
- if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \
- prep_huffman(f); \
- var = f->acc & FAST_HUFFMAN_TABLE_MASK; \
- var = c->fast_huffman[var]; \
- if (var >= 0) { \
- int n = c->codeword_lengths[var]; \
- f->acc >>= n; \
- f->valid_bits -= n; \
- if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \
- } else { \
- var = codebook_decode_scalar_raw(f,c); \
- }
-
- #else
-
- #define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c);
-
- #endif
-
- #define DECODE(var,f,c) \
- DECODE_RAW(var,f,c) \
- if (c->sparse) var = c->sorted_values[var];
-
- #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
- #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c)
- #else
- #define DECODE_VQ(var,f,c) DECODE(var,f,c)
- #endif
-
-
-
-
-
-
- // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case
- // where we avoid one addition
- #ifndef STB_VORBIS_CODEBOOK_FLOATS
- #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off] * c->delta_value + c->minimum_value)
- #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off] * c->delta_value)
- #define CODEBOOK_ELEMENT_BASE(c) (c->minimum_value)
- #else
- #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off])
- #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off])
- #define CODEBOOK_ELEMENT_BASE(c) (0)
- #endif
-
- static int codebook_decode_start(vorb *f, Codebook *c, int len)
- {
- int z = -1;
-
- // type 0 is only legal in a scalar context
- if (c->lookup_type == 0)
- error(f, VORBIS_invalid_stream);
- else {
- DECODE_VQ(z,f,c);
- if (c->sparse) assert(z < c->sorted_entries);
- if (z < 0) { // check for EOP
- if (!f->bytes_in_seg)
- if (f->last_seg)
- return z;
- error(f, VORBIS_invalid_stream);
- }
- }
- return z;
- }
-
- static int codebook_decode(vorb *f, Codebook *c, float *output, int len)
- {
- int i,z = codebook_decode_start(f,c,len);
- if (z < 0) return FALSE;
- if (len > c->dimensions) len = c->dimensions;
-
- #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
- if (c->lookup_type == 1) {
- float last = CODEBOOK_ELEMENT_BASE(c);
- int div = 1;
- for (i=0; i < len; ++i) {
- int off = (z / div) % c->lookup_values;
- float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
- output[i] += val;
- if (c->sequence_p) last = val + c->minimum_value;
- div *= c->lookup_values;
- }
- return TRUE;
- }
- #endif
-
- z *= c->dimensions;
- if (c->sequence_p) {
- float last = CODEBOOK_ELEMENT_BASE(c);
- for (i=0; i < len; ++i) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- output[i] += val;
- last = val + c->minimum_value;
- }
- } else {
- float last = CODEBOOK_ELEMENT_BASE(c);
- for (i=0; i < len; ++i) {
- output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- }
- }
-
- return TRUE;
- }
-
- static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step)
- {
- int i,z = codebook_decode_start(f,c,len);
- float last = CODEBOOK_ELEMENT_BASE(c);
- if (z < 0) return FALSE;
- if (len > c->dimensions) len = c->dimensions;
-
- #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
- if (c->lookup_type == 1) {
- int div = 1;
- for (i=0; i < len; ++i) {
- int off = (z / div) % c->lookup_values;
- float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
- output[i*step] += val;
- if (c->sequence_p) last = val;
- div *= c->lookup_values;
- }
- return TRUE;
- }
- #endif
-
- z *= c->dimensions;
- for (i=0; i < len; ++i) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- output[i*step] += val;
- if (c->sequence_p) last = val;
- }
-
- return TRUE;
- }
-
- static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode)
- {
- int c_inter = *c_inter_p;
- int p_inter = *p_inter_p;
- int i,z, effective = c->dimensions;
-
- // type 0 is only legal in a scalar context
- if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream);
-
- while (total_decode > 0) {
- float last = CODEBOOK_ELEMENT_BASE(c);
- DECODE_VQ(z,f,c);
- #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
- assert(!c->sparse || z < c->sorted_entries);
- #endif
- if (z < 0) {
- if (!f->bytes_in_seg)
- if (f->last_seg) return FALSE;
- return error(f, VORBIS_invalid_stream);
- }
-
- // if this will take us off the end of the buffers, stop short!
- // we check by computing the length of the virtual interleaved
- // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter),
- // and the length we'll be using (effective)
- if (c_inter + p_inter*ch + effective > len * ch) {
- effective = len*ch - (p_inter*ch - c_inter);
- }
-
- #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
- if (c->lookup_type == 1) {
- int div = 1;
- for (i=0; i < effective; ++i) {
- int off = (z / div) % c->lookup_values;
- float val = CODEBOOK_ELEMENT_FAST(c,off) + last;
- outputs[c_inter][p_inter] += val;
- if (++c_inter == ch) { c_inter = 0; ++p_inter; }
- if (c->sequence_p) last = val;
- div *= c->lookup_values;
- }
- } else
- #endif
- {
- z *= c->dimensions;
- if (c->sequence_p) {
- for (i=0; i < effective; ++i) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- outputs[c_inter][p_inter] += val;
- if (++c_inter == ch) { c_inter = 0; ++p_inter; }
- last = val;
- }
- } else {
- for (i=0; i < effective; ++i) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- outputs[c_inter][p_inter] += val;
- if (++c_inter == ch) { c_inter = 0; ++p_inter; }
- }
- }
- }
-
- total_decode -= effective;
- }
- *c_inter_p = c_inter;
- *p_inter_p = p_inter;
- return TRUE;
- }
-
- #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
- static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **outputs, int *c_inter_p, int *p_inter_p, int len, int total_decode)
- {
- int c_inter = *c_inter_p;
- int p_inter = *p_inter_p;
- int i,z, effective = c->dimensions;
-
- // type 0 is only legal in a scalar context
- if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream);
-
- while (total_decode > 0) {
- float last = CODEBOOK_ELEMENT_BASE(c);
- DECODE_VQ(z,f,c);
-
- if (z < 0) {
- if (!f->bytes_in_seg)
- if (f->last_seg) return FALSE;
- return error(f, VORBIS_invalid_stream);
- }
-
- // if this will take us off the end of the buffers, stop short!
- // we check by computing the length of the virtual interleaved
- // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter),
- // and the length we'll be using (effective)
- if (c_inter + p_inter*2 + effective > len * 2) {
- effective = len*2 - (p_inter*2 - c_inter);
- }
-
- {
- z *= c->dimensions;
- stb_prof(11);
- if (c->sequence_p) {
- // haven't optimized this case because I don't have any examples
- for (i=0; i < effective; ++i) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- outputs[c_inter][p_inter] += val;
- if (++c_inter == 2) { c_inter = 0; ++p_inter; }
- last = val;
- }
- } else {
- i=0;
- if (c_inter == 1) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- outputs[c_inter][p_inter] += val;
- c_inter = 0; ++p_inter;
- ++i;
- }
- {
- float *z0 = outputs[0];
- float *z1 = outputs[1];
- for (; i+1 < effective;) {
- z0[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- z1[p_inter] += CODEBOOK_ELEMENT_FAST(c,z+i+1) + last;
- ++p_inter;
- i += 2;
- }
- }
- if (i < effective) {
- float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
- outputs[c_inter][p_inter] += val;
- if (++c_inter == 2) { c_inter = 0; ++p_inter; }
- }
- }
- }
-
- total_decode -= effective;
- }
- *c_inter_p = c_inter;
- *p_inter_p = p_inter;
- return TRUE;
- }
- #endif
-
- static int predict_point(int x, int x0, int x1, int y0, int y1)
- {
- int dy = y1 - y0;
- int adx = x1 - x0;
- // @OPTIMIZE: force int division to round in the right direction... is this necessary on x86?
- int err = abs(dy) * (x - x0);
- int off = err / adx;
- return dy < 0 ? y0 - off : y0 + off;
- }
-
- // the following table is block-copied from the specification
- static float inverse_db_table[256] =
- {
- 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f,
- 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
- 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f,
- 2.2670913e-07f, 2.41…