egra: agg mini clipping bugfix; some fixes in widget rendering (buttons, etc.)
[iv.d.git] / stb / vorbis.d
blob3420514dea0fdd3706fda9ad7f0e45c692c932b4
1 // Ogg Vorbis audio decoder - v1.10 - public domain
2 // http://nothings.org/stb_vorbis/
3 //
4 // Original version written by Sean Barrett in 2007.
5 //
6 // Originally sponsored by RAD Game Tools. Seeking sponsored
7 // by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software,
8 // Aras Pranckevicius, and Sean Barrett.
9 //
10 // LICENSE
12 // See end of file for license information.
14 // Limitations:
16 // - floor 0 not supported (used in old ogg vorbis files pre-2004)
17 // - lossless sample-truncation at beginning ignored
18 // - cannot concatenate multiple vorbis streams
19 // - sample positions are 32-bit, limiting seekable 192Khz
20 // files to around 6 hours (Ogg supports 64-bit)
22 // Feature contributors:
23 // Dougall Johnson (sample-exact seeking)
25 // Bugfix/warning contributors:
26 // Terje Mathisen Niklas Frykholm Andy Hill
27 // Casey Muratori John Bolton Gargaj
28 // Laurent Gomila Marc LeBlanc Ronny Chevalier
29 // Bernhard Wodo Evan Balster alxprd@github
30 // Tom Beaumont Ingo Leitgeb Nicolas Guillemot
31 // Phillip Bennefall Rohit Thiago Goulart
32 // manxorist@github saga musix
34 // Partial history:
35 // 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
36 // 1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
37 // 1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
38 // avoid discarding last frame of audio data
39 // 1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API
40 // some more crash fixes when out of memory or with corrupt files
41 // 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
42 // some crash fixes when out of memory or with corrupt files
43 // fix some inappropriately signed shifts
44 // 1.05 - 2015/04/19 - don't define __forceinline if it's redundant
45 // 1.04 - 2014/08/27 - fix missing const-correct case in API
46 // 1.03 - 2014/08/07 - warning fixes
47 // 1.02 - 2014/07/09 - declare qsort comparison as explicitly _cdecl in Windows
48 // 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float (interleaved was correct)
49 // 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
50 // (API change) report sample rate for decode-full-file funcs
51 // 0.99996 - - bracket #include <malloc.h> for macintosh compilation
52 // 0.99995 - - avoid alias-optimization issue in float-to-int conversion
54 // See end of file for full version history.
55 // D translation by Ketmar // Invisible Vector
56 module iv.stb.vorbis /*is aliced*/;
58 import iv.alice;
59 import core.stdc.stdio : FILE;
61 nothrow /*@trusted*/:
62 @nogc { // code block, as c macro helper is not @nogc; yet it's CTFE-only
63 // import it here, as druntime has no `@nogc` on it (for a reason)
64 private extern(C) void qsort (void* base, usize nmemb, usize size, int function(in void*, in void*) compar);
67 //////////////////////////////////////////////////////////////////////////////
69 // HEADER BEGINS HERE
72 /////////// THREAD SAFETY
74 // Individual VorbisDecoder handles are not thread-safe; you cannot decode from
75 // them from multiple threads at the same time. However, you can have multiple
76 // VorbisDecoder handles and decode from them independently in multiple thrads.
79 /////////// MEMORY ALLOCATION
81 // normally stb_vorbis uses malloc() to allocate memory at startup,
82 // and alloca() to allocate temporary memory during a frame on the
83 // stack. (Memory consumption will depend on the amount of setup
84 // data in the file and how you set the compile flags for speed
85 // vs. size. In my test files the maximal-size usage is ~150KB.)
87 // You can modify the wrapper functions in the source (setup_malloc,
88 // setup_temp_malloc, temp_malloc) to change this behavior, or you
89 // can use a simpler allocation model: you pass in a buffer from
90 // which stb_vorbis will allocate _all_ its memory (including the
91 // temp memory). "open" may fail with a VORBIS_outofmem if you
92 // do not pass in enough data; there is no way to determine how
93 // much you do need except to succeed (at which point you can
94 // query get_info to find the exact amount required. yes I know
95 // this is lame).
97 // If you pass in a non-null buffer of the type below, allocation
98 // will occur from it as described above. Otherwise just pass null
99 // to use malloc()/alloca()
101 public struct stb_vorbis_alloc {
102 ubyte* alloc_buffer;
103 int alloc_buffer_length_in_bytes;
107 /////////// FUNCTIONS USEABLE WITH ALL INPUT MODES
110 public struct stb_vorbis_info {
111 uint sample_rate;
112 int channels;
114 uint setup_memory_required;
115 uint setup_temp_memory_required;
116 uint temp_memory_required;
118 int max_frame_size;
123 /* ************************************************************************** *
124 // get general information about the file
125 stb_vorbis_info stb_vorbis_get_info (VorbisDecoder f);
127 // get the last error detected (clears it, too)
128 int stb_vorbis_get_error (VorbisDecoder f);
130 // close an ogg vorbis file and free all memory in use
131 void stb_vorbis_close (VorbisDecoder f);
133 // this function returns the offset (in samples) from the beginning of the
134 // file that will be returned by the next decode, if it is known, or -1
135 // otherwise. after a flush_pushdata() call, this may take a while before
136 // it becomes valid again.
137 // NOT WORKING YET after a seek with PULLDATA API
138 int stb_vorbis_get_sample_offset (VorbisDecoder f);
140 // returns the current seek point within the file, or offset from the beginning
141 // of the memory buffer. In pushdata mode it returns 0.
142 uint stb_vorbis_get_file_offset (VorbisDecoder f);
145 /////////// PUSHDATA API
147 // this API allows you to get blocks of data from any source and hand
148 // them to stb_vorbis. you have to buffer them; stb_vorbis will tell
149 // you how much it used, and you have to give it the rest next time;
150 // and stb_vorbis may not have enough data to work with and you will
151 // need to give it the same data again PLUS more. Note that the Vorbis
152 // specification does not bound the size of an individual frame.
154 // create a vorbis decoder by passing in the initial data block containing
155 // the ogg&vorbis headers (you don't need to do parse them, just provide
156 // the first N bytes of the file--you're told if it's not enough, see below)
157 // on success, returns an VorbisDecoder, does not set error, returns the amount of
158 // data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
159 // on failure, returns null on error and sets *error, does not change *datablock_memory_consumed
160 // if returns null and *error is VORBIS_need_more_data, then the input block was
161 // incomplete and you need to pass in a larger block from the start of the file
162 VorbisDecoder stb_vorbis_open_pushdata (
163 ubyte* datablock, int datablock_length_in_bytes,
164 int* datablock_memory_consumed_in_bytes,
165 int* error,
166 stb_vorbis_alloc* alloc_buffer
169 // decode a frame of audio sample data if possible from the passed-in data block
171 // return value: number of bytes we used from datablock
173 // possible cases:
174 // 0 bytes used, 0 samples output (need more data)
175 // N bytes used, 0 samples output (resynching the stream, keep going)
176 // N bytes used, M samples output (one frame of data)
177 // note that after opening a file, you will ALWAYS get one N-bytes, 0-sample
178 // frame, because Vorbis always "discards" the first frame.
180 // Note that on resynch, stb_vorbis will rarely consume all of the buffer,
181 // instead only datablock_length_in_bytes-3 or less. This is because it wants
182 // to avoid missing parts of a page header if they cross a datablock boundary,
183 // without writing state-machiney code to record a partial detection.
185 // The number of channels returned are stored in *channels (which can be
186 // null--it is always the same as the number of channels reported by
187 // get_info). *output will contain an array of float* buffers, one per
188 // channel. In other words, (*output)[0][0] contains the first sample from
189 // the first channel, and (*output)[1][0] contains the first sample from
190 // the second channel.
191 int stb_vorbis_decode_frame_pushdata (
192 VorbisDecoder f, ubyte* datablock, int datablock_length_in_bytes,
193 int* channels, // place to write number of float * buffers
194 float*** output, // place to write float ** array of float * buffers
195 int* samples // place to write number of output samples
198 // inform stb_vorbis that your next datablock will not be contiguous with
199 // previous ones (e.g. you've seeked in the data); future attempts to decode
200 // frames will cause stb_vorbis to resynchronize (as noted above), and
201 // once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
202 // will begin decoding the _next_ frame.
204 // if you want to seek using pushdata, you need to seek in your file, then
205 // call stb_vorbis_flush_pushdata(), then start calling decoding, then once
206 // decoding is returning you data, call stb_vorbis_get_sample_offset, and
207 // if you don't like the result, seek your file again and repeat.
208 void stb_vorbis_flush_pushdata (VorbisDecoder f);
211 ////////// PULLING INPUT API
213 // This API assumes stb_vorbis is allowed to pull data from a source--
214 // either a block of memory containing the _entire_ vorbis stream, or a
215 // FILE* that you or it create, or possibly some other reading mechanism
216 // if you go modify the source to replace the FILE* case with some kind
217 // of callback to your code. (But if you don't support seeking, you may
218 // just want to go ahead and use pushdata.)
220 // decode an entire file and output the data interleaved into a malloc()ed
221 // buffer stored in *output. The return value is the number of samples
222 // decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
223 // When you're done with it, just free() the pointer returned in *output.
224 int stb_vorbis_decode_filename (const(char)* filename, int* channels, int* sample_rate, short** output);
225 int stb_vorbis_decode_memory (const(ubyte)* mem, int len, int* channels, int* sample_rate, short** output);
227 // create an ogg vorbis decoder from an ogg vorbis stream in memory (note
228 // this must be the entire stream!). on failure, returns null and sets *error
229 VorbisDecoder stb_vorbis_open_memory (const(ubyte)* data, int len, int* error, stb_vorbis_alloc* alloc_buffer);
231 // create an ogg vorbis decoder from a filename via fopen(). on failure,
232 // returns null and sets *error (possibly to VORBIS_file_open_failure).
233 VorbisDecoder stb_vorbis_open_filename (const(char)* filename, int* error, stb_vorbis_alloc* alloc_buffer);
235 // create an ogg vorbis decoder from an open FILE*, looking for a stream at
236 // the _current_ seek point (ftell). on failure, returns null and sets *error.
237 // note that stb_vorbis must "own" this stream; if you seek it in between
238 // calls to stb_vorbis, it will become confused. Morever, if you attempt to
239 // perform stb_vorbis_seek_*() operations on this file, it will assume it
240 // owns the _entire_ rest of the file after the start point. Use the next
241 // function, stb_vorbis_open_file_section(), to limit it.
242 VorbisDecoder stb_vorbis_open_file (FILE* f, int close_handle_on_close, int* error, stb_vorbis_alloc* alloc_buffer);
244 // create an ogg vorbis decoder from an open FILE*, looking for a stream at
245 // the _current_ seek point (ftell); the stream will be of length 'len' bytes.
246 // on failure, returns null and sets *error. note that stb_vorbis must "own"
247 // this stream; if you seek it in between calls to stb_vorbis, it will become
248 // confused.
249 VorbisDecoder stb_vorbis_open_file_section (FILE* f, int close_handle_on_close, int* error, stb_vorbis_alloc* alloc_buffer, uint len);
251 // these functions seek in the Vorbis file to (approximately) 'sample_number'.
252 // after calling seek_frame(), the next call to get_frame_*() will include
253 // the specified sample. after calling stb_vorbis_seek(), the next call to
254 // stb_vorbis_get_samples_* will start with the specified sample. If you
255 // do not need to seek to EXACTLY the target sample when using get_samples_*,
256 // you can also use seek_frame().
257 int stb_vorbis_seek_frame (VorbisDecoder f, uint sample_number);
258 int stb_vorbis_seek (VorbisDecoder f, uint sample_number);
260 // this function is equivalent to stb_vorbis_seek(f, 0)
261 int stb_vorbis_seek_start (VorbisDecoder f);
263 // these functions return the total length of the vorbis stream
264 uint stb_vorbis_stream_length_in_samples (VorbisDecoder f);
265 float stb_vorbis_stream_length_in_seconds (VorbisDecoder f);
267 // decode the next frame and return the number of samples. the number of
268 // channels returned are stored in *channels (which can be null--it is always
269 // the same as the number of channels reported by get_info). *output will
270 // contain an array of float* buffers, one per channel. These outputs will
271 // be overwritten on the next call to stb_vorbis_get_frame_*.
273 // You generally should not intermix calls to stb_vorbis_get_frame_*()
274 // and stb_vorbis_get_samples_*(), since the latter calls the former.
275 int stb_vorbis_get_frame_float (VorbisDecoder f, int* channels, float*** output);
277 // decode the next frame and return the number of *samples* per channel.
278 // Note that for interleaved data, you pass in the number of shorts (the
279 // size of your array), but the return value is the number of samples per
280 // channel, not the total number of samples.
282 // The data is coerced to the number of channels you request according to the
283 // channel coercion rules (see below). You must pass in the size of your
284 // buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
285 // The maximum buffer size needed can be gotten from get_info(); however,
286 // the Vorbis I specification implies an absolute maximum of 4096 samples
287 // per channel.
288 int stb_vorbis_get_frame_short_interleaved (VorbisDecoder f, int num_c, short* buffer, int num_shorts);
289 int stb_vorbis_get_frame_short (VorbisDecoder f, int num_c, short** buffer, int num_samples);
291 // Channel coercion rules:
292 // Let M be the number of channels requested, and N the number of channels present,
293 // and Cn be the nth channel; let stereo L be the sum of all L and center channels,
294 // and stereo R be the sum of all R and center channels (channel assignment from the
295 // vorbis spec).
296 // M N output
297 // 1 k sum(Ck) for all k
298 // 2 * stereo L, stereo R
299 // k l k > l, the first l channels, then 0s
300 // k l k <= l, the first k channels
301 // Note that this is not _good_ surround etc. mixing at all! It's just so
302 // you get something useful.
304 // gets num_samples samples, not necessarily on a frame boundary--this requires
305 // buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
306 // Returns the number of samples stored per channel; it may be less than requested
307 // at the end of the file. If there are no more samples in the file, returns 0.
308 int stb_vorbis_get_samples_float_interleaved (VorbisDecoder f, int channels, float* buffer, int num_floats);
309 int stb_vorbis_get_samples_float (VorbisDecoder f, int channels, float** buffer, int num_samples);
311 // gets num_samples samples, not necessarily on a frame boundary--this requires
312 // buffering so you have to supply the buffers. Applies the coercion rules above
313 // to produce 'channels' channels. Returns the number of samples stored per channel;
314 // it may be less than requested at the end of the file. If there are no more
315 // samples in the file, returns 0.
316 int stb_vorbis_get_samples_short_interleaved (VorbisDecoder f, int channels, short* buffer, int num_shorts);
317 int stb_vorbis_get_samples_short (VorbisDecoder f, int channels, short** buffer, int num_samples);
320 //////// ERROR CODES
322 public enum STBVorbisError {
323 no_error,
325 need_more_data = 1, // not a real error
327 invalid_api_mixing, // can't mix API modes
328 outofmem, // not enough memory
329 feature_not_supported, // uses floor 0
330 too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
331 file_open_failure, // fopen() failed
332 seek_without_length, // can't seek in unknown-length file
334 unexpected_eof = 10, // file is truncated?
335 seek_invalid, // seek past EOF
337 // decoding errors (corrupt/invalid stream) -- you probably
338 // don't care about the exact details of these
340 // vorbis errors:
341 invalid_setup = 20,
342 invalid_stream,
344 // ogg errors:
345 missing_capture_pattern = 30,
346 invalid_stream_structure_version,
347 continued_packet_flag_invalid,
348 incorrect_stream_serial_number,
349 invalid_first_page,
350 bad_packet_type,
351 cant_find_last_page,
352 seek_failed,
355 // HEADER ENDS HERE
357 //////////////////////////////////////////////////////////////////////////////
360 // global configuration settings (e.g. set these in the project/makefile),
361 // or just set them in this file at the top (although ideally the first few
362 // should be visible when the header file is compiled too, although it's not
363 // crucial)
365 // STB_VORBIS_NO_INTEGER_CONVERSION
366 // does not compile the code for converting audio sample data from
367 // float to integer (implied by STB_VORBIS_NO_PULLDATA_API)
368 //version = STB_VORBIS_NO_INTEGER_CONVERSION;
370 // STB_VORBIS_NO_FAST_SCALED_FLOAT
371 // does not use a fast float-to-int trick to accelerate float-to-int on
372 // most platforms which requires endianness be defined correctly.
373 //version = STB_VORBIS_NO_FAST_SCALED_FLOAT;
375 // STB_VORBIS_MAX_CHANNELS [number]
376 // globally define this to the maximum number of channels you need.
377 // The spec does not put a restriction on channels except that
378 // the count is stored in a byte, so 255 is the hard limit.
379 // Reducing this saves about 16 bytes per value, so using 16 saves
380 // (255-16)*16 or around 4KB. Plus anything other memory usage
381 // I forgot to account for. Can probably go as low as 8 (7.1 audio),
382 // 6 (5.1 audio), or 2 (stereo only).
383 enum STB_VORBIS_MAX_CHANNELS = 16; // enough for anyone?
385 // STB_VORBIS_PUSHDATA_CRC_COUNT [number]
386 // after a flush_pushdata(), stb_vorbis begins scanning for the
387 // next valid page, without backtracking. when it finds something
388 // that looks like a page, it streams through it and verifies its
389 // CRC32. Should that validation fail, it keeps scanning. But it's
390 // possible that _while_ streaming through to check the CRC32 of
391 // one candidate page, it sees another candidate page. This #define
392 // determines how many "overlapping" candidate pages it can search
393 // at once. Note that "real" pages are typically ~4KB to ~8KB, whereas
394 // garbage pages could be as big as 64KB, but probably average ~16KB.
395 // So don't hose ourselves by scanning an apparent 64KB page and
396 // missing a ton of real ones in the interim; so minimum of 2
397 enum STB_VORBIS_PUSHDATA_CRC_COUNT = 4;
399 // STB_VORBIS_FAST_HUFFMAN_LENGTH [number]
400 // sets the log size of the huffman-acceleration table. Maximum
401 // supported value is 24. with larger numbers, more decodings are O(1),
402 // but the table size is larger so worse cache missing, so you'll have
403 // to probe (and try multiple ogg vorbis files) to find the sweet spot.
404 enum STB_VORBIS_FAST_HUFFMAN_LENGTH = 10;
406 // STB_VORBIS_FAST_BINARY_LENGTH [number]
407 // sets the log size of the binary-search acceleration table. this
408 // is used in similar fashion to the fast-huffman size to set initial
409 // parameters for the binary search
411 // STB_VORBIS_FAST_HUFFMAN_INT
412 // The fast huffman tables are much more efficient if they can be
413 // stored as 16-bit results instead of 32-bit results. This restricts
414 // the codebooks to having only 65535 possible outcomes, though.
415 // (At least, accelerated by the huffman table.)
416 //version = STB_VORBIS_FAST_HUFFMAN_INT;
417 version(STB_VORBIS_FAST_HUFFMAN_INT) {} else version = STB_VORBIS_FAST_HUFFMAN_SHORT;
419 // STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
420 // If the 'fast huffman' search doesn't succeed, then stb_vorbis falls
421 // back on binary searching for the correct one. This requires storing
422 // extra tables with the huffman codes in sorted order. Defining this
423 // symbol trades off space for speed by forcing a linear search in the
424 // non-fast case, except for "sparse" codebooks.
425 //version = STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH;
427 // STB_VORBIS_DIVIDES_IN_RESIDUE
428 // stb_vorbis precomputes the result of the scalar residue decoding
429 // that would otherwise require a divide per chunk. you can trade off
430 // space for time by defining this symbol.
431 //version = STB_VORBIS_DIVIDES_IN_RESIDUE;
433 // STB_VORBIS_DIVIDES_IN_CODEBOOK
434 // vorbis VQ codebooks can be encoded two ways: with every case explicitly
435 // stored, or with all elements being chosen from a small range of values,
436 // and all values possible in all elements. By default, stb_vorbis expands
437 // this latter kind out to look like the former kind for ease of decoding,
438 // because otherwise an integer divide-per-vector-element is required to
439 // unpack the index. If you define STB_VORBIS_DIVIDES_IN_CODEBOOK, you can
440 // trade off storage for speed.
441 //version = STB_VORBIS_DIVIDES_IN_CODEBOOK;
443 version(STB_VORBIS_CODEBOOK_SHORTS) static assert(0, "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats");
445 // STB_VORBIS_DIVIDE_TABLE
446 // this replaces small integer divides in the floor decode loop with
447 // table lookups. made less than 1% difference, so disabled by default.
448 //version = STB_VORBIS_DIVIDE_TABLE;
450 // STB_VORBIS_NO_DEFER_FLOOR
451 // Normally we only decode the floor without synthesizing the actual
452 // full curve. We can instead synthesize the curve immediately. This
453 // requires more memory and is very likely slower, so I don't think
454 // you'd ever want to do it except for debugging.
455 //version = STB_VORBIS_NO_DEFER_FLOOR;
456 //version(STB_VORBIS_CODEBOOK_FLOATS) static assert(0);
459 // ////////////////////////////////////////////////////////////////////////// //
460 private:
461 static assert(STB_VORBIS_MAX_CHANNELS <= 256, "Value of STB_VORBIS_MAX_CHANNELS outside of allowed range");
462 static assert(STB_VORBIS_FAST_HUFFMAN_LENGTH <= 24, "Value of STB_VORBIS_FAST_HUFFMAN_LENGTH outside of allowed range");
464 enum MAX_BLOCKSIZE_LOG = 13; // from specification
465 enum MAX_BLOCKSIZE = (1 << MAX_BLOCKSIZE_LOG);
468 alias codetype = float;
470 // @NOTE
472 // Some arrays below are tagged "//varies", which means it's actually
473 // a variable-sized piece of data, but rather than malloc I assume it's
474 // small enough it's better to just allocate it all together with the
475 // main thing
477 // Most of the variables are specified with the smallest size I could pack
478 // them into. It might give better performance to make them all full-sized
479 // integers. It should be safe to freely rearrange the structures or change
480 // the sizes larger--nothing relies on silently truncating etc., nor the
481 // order of variables.
483 enum FAST_HUFFMAN_TABLE_SIZE = (1<<STB_VORBIS_FAST_HUFFMAN_LENGTH);
484 enum FAST_HUFFMAN_TABLE_MASK = (FAST_HUFFMAN_TABLE_SIZE-1);
486 struct Codebook {
487 int dimensions, entries;
488 ubyte* codeword_lengths;
489 float minimum_value;
490 float delta_value;
491 ubyte value_bits;
492 ubyte lookup_type;
493 ubyte sequence_p;
494 ubyte sparse;
495 uint lookup_values;
496 codetype* multiplicands;
497 uint *codewords;
498 version(STB_VORBIS_FAST_HUFFMAN_SHORT) {
499 short[FAST_HUFFMAN_TABLE_SIZE] fast_huffman;
500 } else {
501 int[FAST_HUFFMAN_TABLE_SIZE] fast_huffman;
503 uint* sorted_codewords;
504 int* sorted_values;
505 int sorted_entries;
508 struct Floor0 {
509 ubyte order;
510 ushort rate;
511 ushort bark_map_size;
512 ubyte amplitude_bits;
513 ubyte amplitude_offset;
514 ubyte number_of_books;
515 ubyte[16] book_list; // varies
518 struct Floor1 {
519 ubyte partitions;
520 ubyte[32] partition_class_list; // varies
521 ubyte[16] class_dimensions; // varies
522 ubyte[16] class_subclasses; // varies
523 ubyte[16] class_masterbooks; // varies
524 short[8][16] subclass_books; // varies
525 ushort[31*8+2] Xlist; // varies
526 ubyte[31*8+2] sorted_order;
527 ubyte[2][31*8+2] neighbors;
528 ubyte floor1_multiplier;
529 ubyte rangebits;
530 int values;
533 union Floor {
534 Floor0 floor0;
535 Floor1 floor1;
538 struct Residue {
539 uint begin, end;
540 uint part_size;
541 ubyte classifications;
542 ubyte classbook;
543 ubyte** classdata;
544 //int16 (*residue_books)[8];
545 short[8]* residue_books;
548 struct MappingChannel {
549 ubyte magnitude;
550 ubyte angle;
551 ubyte mux;
554 struct Mapping {
555 ushort coupling_steps;
556 MappingChannel* chan;
557 ubyte submaps;
558 ubyte[15] submap_floor; // varies
559 ubyte[15] submap_residue; // varies
562 struct Mode {
563 ubyte blockflag;
564 ubyte mapping;
565 ushort windowtype;
566 ushort transformtype;
569 struct CRCscan {
570 uint goal_crc; // expected crc if match
571 int bytes_left; // bytes left in packet
572 uint crc_so_far; // running crc
573 int bytes_done; // bytes processed in _current_ chunk
574 uint sample_loc; // granule pos encoded in page
577 struct ProbedPage {
578 uint page_start, page_end;
579 uint last_decoded_sample;
582 private int error (VorbisDecoder f, STBVorbisError e) {
583 f.error = e;
584 if (!f.eof && e != STBVorbisError.need_more_data) {
585 f.error = e; // breakpoint for debugging
587 return 0;
590 // these functions are used for allocating temporary memory
591 // while decoding. if you can afford the stack space, use
592 // alloca(); otherwise, provide a temp buffer and it will
593 // allocate out of those.
594 uint temp_alloc_save (VorbisDecoder f) nothrow @nogc { static if (__VERSION__ > 2067) pragma(inline, true); return f.alloc.tempSave(f); }
595 void temp_alloc_restore (VorbisDecoder f, uint p) nothrow @nogc { static if (__VERSION__ > 2067) pragma(inline, true); f.alloc.tempRestore(p, f); }
596 void temp_free (VorbisDecoder f, void* p) nothrow @nogc {}
598 T* temp_alloc(T) (VorbisDecoder f, uint count) nothrow @nogc {
599 auto res = f.alloc.alloc(count*T.sizeof, f);
600 return cast(T*)res;
605 enum array_size_required(string count, string size) = q{((${count})*((void*).sizeof+(${size})))}.cmacroFixVars!("count", "size")(count, size);
607 // has to be a mixin, due to `alloca`
608 template temp_alloc(string size) {
609 enum temp_alloc = q{(f.alloc.alloc_buffer ? setup_temp_malloc(f, (${size})) : alloca(${size}))}.cmacroFixVars!("size")(size);
612 // has to be a mixin, due to `alloca`
613 template temp_block_array(string count, string size) {
614 enum temp_block_array = q{(make_block_array(${tam}, (${count}), (${size})))}
615 .cmacroFixVars!("count", "size", "tam")(count, size, temp_alloc!(array_size_required!(count, size)));
618 enum array_size_required(string count, string size) = q{((${count})*((void*).sizeof+(${size})))}.cmacroFixVars!("count", "size")(count, size);
620 template temp_alloc(string size) {
621 enum temp_alloc = q{alloca(${size})}.cmacroFixVars!("size")(size);
624 template temp_block_array(string count, string size) {
625 enum temp_block_array = q{(make_block_array(${tam}, (${count}), (${size})))}
626 .cmacroFixVars!("count", "size", "tam")(count, size, temp_alloc!(array_size_required!(count, size)));
630 T** temp_block_array(T) (VorbisDecoder f, uint count, uint size) {
631 size *= T.sizeof;
632 auto mem = f.alloc.alloc(count*(void*).sizeof+size, f);
633 if (mem !is null) make_block_array(mem, count, size);
634 return cast(T**)mem;
638 // given a sufficiently large block of memory, make an array of pointers to subblocks of it
639 private void* make_block_array (void* mem, int count, int size) {
640 void** p = cast(void**)mem;
641 char* q = cast(char*)(p+count);
642 foreach (immutable i; 0..count) {
643 p[i] = q;
644 q += size;
646 return p;
649 private T* setup_malloc(T) (VorbisDecoder f, uint sz) {
650 sz *= T.sizeof;
652 f.setup_memory_required += sz;
653 if (f.alloc.alloc_buffer) {
654 void* p = cast(char*)f.alloc.alloc_buffer+f.setup_offset;
655 if (f.setup_offset+sz > f.temp_offset) return null;
656 f.setup_offset += sz;
657 return cast(T*)p;
660 auto res = f.alloc.alloc(sz+8, f); // +8 to compensate dmd codegen bug: it can read dword(qword?) when told to read only byte
661 if (res !is null) {
662 import core.stdc.string : memset;
663 memset(res, 0, sz+8);
665 return cast(T*)res;
668 private void setup_free (VorbisDecoder f, void* p) {
669 //if (f.alloc.alloc_buffer) return; // do nothing; setup mem is a stack
670 if (p !is null) f.alloc.free(p, f);
673 private void* setup_temp_malloc (VorbisDecoder f, uint sz) {
674 auto res = f.alloc.allocTemp(sz+8, f); // +8 to compensate dmd codegen bug: it can read dword(qword?) when told to read only byte
675 if (res !is null) {
676 import core.stdc.string : memset;
677 memset(res, 0, sz+8);
679 return res;
682 private void setup_temp_free (VorbisDecoder f, void* p, uint sz) {
683 if (p !is null) f.alloc.freeTemp(p, (sz ? sz : 1)+8, f); // +8 to compensate dmd codegen bug: it can read dword(qword?) when told to read only byte
686 immutable uint[256] crc_table;
687 shared static this () {
688 enum CRC32_POLY = 0x04c11db7; // from spec
689 // init crc32 table
690 foreach (uint i; 0..256) {
691 uint s = i<<24;
692 foreach (immutable _; 0..8) s = (s<<1)^(s >= (1U<<31) ? CRC32_POLY : 0);
693 crc_table[i] = s;
697 uint crc32_update (uint crc, ubyte b) {
698 static if (__VERSION__ > 2067) pragma(inline, true);
699 return (crc<<8)^crc_table[b^(crc>>24)];
702 // used in setup, and for huffman that doesn't go fast path
703 private uint bit_reverse (uint n) {
704 static if (__VERSION__ > 2067) pragma(inline, true);
705 n = ((n&0xAAAAAAAA)>>1)|((n&0x55555555)<<1);
706 n = ((n&0xCCCCCCCC)>>2)|((n&0x33333333)<<2);
707 n = ((n&0xF0F0F0F0)>>4)|((n&0x0F0F0F0F)<<4);
708 n = ((n&0xFF00FF00)>>8)|((n&0x00FF00FF)<<8);
709 return (n>>16)|(n<<16);
712 private float square (float x) {
713 static if (__VERSION__ > 2067) pragma(inline, true);
714 return x*x;
717 // this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3
718 // as required by the specification. fast(?) implementation from stb.h
719 // @OPTIMIZE: called multiple times per-packet with "constants"; move to setup
720 immutable byte[16] log2_4 = [0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];
721 private int ilog (int n) {
722 //static if (__VERSION__ > 2067) pragma(inline, true);
723 if (n < 0) return 0; // signed n returns 0
724 // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
725 if (n < (1<<14)) {
726 if (n < (1<<4)) return 0+log2_4[n];
727 if (n < (1<<9)) return 5+log2_4[n>>5];
728 return 10+log2_4[n>>10];
729 } else if (n < (1<<24)) {
730 if (n < (1<<19)) return 15+log2_4[n>>15];
731 return 20+log2_4[n>>20];
732 } else {
733 if (n < (1<<29)) return 25+log2_4[n>>25];
734 return 30+log2_4[n>>30];
739 // code length assigned to a value with no huffman encoding
740 enum NO_CODE = 255;
742 /////////////////////// LEAF SETUP FUNCTIONS //////////////////////////
744 // these functions are only called at setup, and only a few times per file
745 private float float32_unpack (uint x) {
746 import core.math : ldexp;
747 //static if (__VERSION__ > 2067) pragma(inline, true);
748 // from the specification
749 uint mantissa = x&0x1fffff;
750 uint sign = x&0x80000000;
751 uint exp = (x&0x7fe00000)>>21;
752 double res = (sign ? -cast(double)mantissa : cast(double)mantissa);
753 return cast(float)ldexp(cast(float)res, exp-788);
756 // zlib & jpeg huffman tables assume that the output symbols
757 // can either be arbitrarily arranged, or have monotonically
758 // increasing frequencies--they rely on the lengths being sorted;
759 // this makes for a very simple generation algorithm.
760 // vorbis allows a huffman table with non-sorted lengths. This
761 // requires a more sophisticated construction, since symbols in
762 // order do not map to huffman codes "in order".
763 private void add_entry (Codebook* c, uint huff_code, int symbol, int count, ubyte len, uint* values) {
764 if (!c.sparse) {
765 c.codewords[symbol] = huff_code;
766 } else {
767 c.codewords[count] = huff_code;
768 c.codeword_lengths[count] = len;
769 values[count] = symbol;
773 private int compute_codewords (Codebook* c, ubyte* len, int n, uint* values) {
774 import core.stdc.string : memset;
776 int i, k, m = 0;
777 uint[32] available;
779 memset(available.ptr, 0, available.sizeof);
780 // find the first entry
781 for (k = 0; k < n; ++k) if (len[k] < NO_CODE) break;
782 if (k == n) { assert(c.sorted_entries == 0); return true; }
783 // add to the list
784 add_entry(c, 0, k, m++, len[k], values);
785 // add all available leaves
786 for (i = 1; i <= len[k]; ++i) available[i] = 1U<<(32-i);
787 // note that the above code treats the first case specially,
788 // but it's really the same as the following code, so they
789 // could probably be combined (except the initial code is 0,
790 // and I use 0 in available[] to mean 'empty')
791 for (i = k+1; i < n; ++i) {
792 uint res;
793 int z = len[i];
794 if (z == NO_CODE) continue;
795 // find lowest available leaf (should always be earliest,
796 // which is what the specification calls for)
797 // note that this property, and the fact we can never have
798 // more than one free leaf at a given level, isn't totally
799 // trivial to prove, but it seems true and the assert never
800 // fires, so!
801 while (z > 0 && !available[z]) --z;
802 if (z == 0) return false;
803 res = available[z];
804 assert(z >= 0 && z < 32);
805 available[z] = 0;
806 ubyte xxx = len[i];
807 add_entry(c,
808 bit_reverse(res),
810 m++,
811 xxx, // dmd bug: it reads 4 bytes without temp
812 values);
813 // propogate availability up the tree
814 if (z != len[i]) {
815 assert(len[i] >= 0 && len[i] < 32);
816 for (int y = len[i]; y > z; --y) {
817 assert(available[y] == 0);
818 available[y] = res+(1<<(32-y));
822 return true;
825 // accelerated huffman table allows fast O(1) match of all symbols
826 // of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH
827 private void compute_accelerated_huffman (Codebook* c) {
828 //for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) c.fast_huffman.ptr[i] = -1;
829 c.fast_huffman.ptr[0..FAST_HUFFMAN_TABLE_SIZE] = -1;
830 auto len = (c.sparse ? c.sorted_entries : c.entries);
831 version(STB_VORBIS_FAST_HUFFMAN_SHORT) {
832 if (len > 32767) len = 32767; // largest possible value we can encode!
834 foreach (uint i; 0..len) {
835 if (c.codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) {
836 uint z = (c.sparse ? bit_reverse(c.sorted_codewords[i]) : c.codewords[i]);
837 // set table entries for all bit combinations in the higher bits
838 while (z < FAST_HUFFMAN_TABLE_SIZE) {
839 c.fast_huffman.ptr[z] = cast(typeof(c.fast_huffman[0]))i; //k8
840 z += 1<<c.codeword_lengths[i];
846 extern(C) int uint32_compare (const void* p, const void* q) {
847 uint x = *cast(uint*)p;
848 uint y = *cast(uint*)q;
849 return (x < y ? -1 : x > y);
852 private int include_in_sort (Codebook* c, uint len) {
853 if (c.sparse) { assert(len != NO_CODE); return true; }
854 if (len == NO_CODE) return false;
855 if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return true;
856 return false;
859 // if the fast table above doesn't work, we want to binary
860 // search them... need to reverse the bits
861 private void compute_sorted_huffman (Codebook* c, ubyte* lengths, uint* values) {
862 // build a list of all the entries
863 // OPTIMIZATION: don't include the short ones, since they'll be caught by FAST_HUFFMAN.
864 // this is kind of a frivolous optimization--I don't see any performance improvement,
865 // but it's like 4 extra lines of code, so.
866 if (!c.sparse) {
867 int k = 0;
868 foreach (uint i; 0..c.entries) if (include_in_sort(c, lengths[i])) c.sorted_codewords[k++] = bit_reverse(c.codewords[i]);
869 assert(k == c.sorted_entries);
870 } else {
871 foreach (uint i; 0..c.sorted_entries) c.sorted_codewords[i] = bit_reverse(c.codewords[i]);
874 qsort(c.sorted_codewords, c.sorted_entries, (c.sorted_codewords[0]).sizeof, &uint32_compare);
875 c.sorted_codewords[c.sorted_entries] = 0xffffffff;
877 auto len = (c.sparse ? c.sorted_entries : c.entries);
878 // now we need to indicate how they correspond; we could either
879 // #1: sort a different data structure that says who they correspond to
880 // #2: for each sorted entry, search the original list to find who corresponds
881 // #3: for each original entry, find the sorted entry
882 // #1 requires extra storage, #2 is slow, #3 can use binary search!
883 foreach (uint i; 0..len) {
884 auto huff_len = (c.sparse ? lengths[values[i]] : lengths[i]);
885 if (include_in_sort(c, huff_len)) {
886 uint code = bit_reverse(c.codewords[i]);
887 int x = 0, n = c.sorted_entries;
888 while (n > 1) {
889 // invariant: sc[x] <= code < sc[x+n]
890 int m = x+(n>>1);
891 if (c.sorted_codewords[m] <= code) {
892 x = m;
893 n -= (n>>1);
894 } else {
895 n >>= 1;
898 assert(c.sorted_codewords[x] == code);
899 if (c.sparse) {
900 c.sorted_values[x] = values[i];
901 c.codeword_lengths[x] = huff_len;
902 } else {
903 c.sorted_values[x] = i;
909 // only run while parsing the header (3 times)
910 private int vorbis_validate (const(void)* data) {
911 static if (__VERSION__ > 2067) pragma(inline, true);
912 immutable char[6] vorbis = "vorbis";
913 return ((cast(char*)data)[0..6] == vorbis[]);
916 // called from setup only, once per code book
917 // (formula implied by specification)
918 private int lookup1_values (int entries, int dim) {
919 import core.stdc.math : lrintf;
920 import std.math : floor, exp, pow, log;
921 int r = cast(int)lrintf(floor(exp(cast(float)log(cast(float)entries)/dim)));
922 if (lrintf(floor(pow(cast(float)r+1, dim))) <= entries) ++r; // (int) cast for MinGW warning; floor() to avoid _ftol() when non-CRT
923 assert(pow(cast(float)r+1, dim) > entries);
924 assert(lrintf(floor(pow(cast(float)r, dim))) <= entries); // (int), floor() as above
925 return r;
928 // called twice per file
929 private void compute_twiddle_factors (int n, float* A, float* B, float* C) {
930 import std.math : cos, sin, PI;
931 int n4 = n>>2, n8 = n>>3;
932 int k, k2;
933 for (k = k2 = 0; k < n4; ++k, k2 += 2) {
934 A[k2 ] = cast(float) cos(4*k*PI/n);
935 A[k2+1] = cast(float)-sin(4*k*PI/n);
936 B[k2 ] = cast(float) cos((k2+1)*PI/n/2)*0.5f;
937 B[k2+1] = cast(float) sin((k2+1)*PI/n/2)*0.5f;
939 for (k = k2 = 0; k < n8; ++k, k2 += 2) {
940 C[k2 ] = cast(float) cos(2*(k2+1)*PI/n);
941 C[k2+1] = cast(float)-sin(2*(k2+1)*PI/n);
945 private void compute_window (int n, float* window) {
946 import std.math : sin, PI;
947 int n2 = n>>1;
948 foreach (int i; 0..n2) *window++ = cast(float)sin(0.5*PI*square(cast(float)sin((i-0+0.5)/n2*0.5*PI)));
951 private void compute_bitreverse (int n, ushort* rev) {
952 int ld = ilog(n)-1; // ilog is off-by-one from normal definitions
953 int n8 = n>>3;
954 foreach (int i; 0..n8) *rev++ = cast(ushort)((bit_reverse(i)>>(32-ld+3))<<2); //k8
957 private int init_blocksize (VorbisDecoder f, int b, int n) {
958 int n2 = n>>1, n4 = n>>2, n8 = n>>3;
959 f.A[b] = setup_malloc!float(f, n2);
960 f.B[b] = setup_malloc!float(f, n2);
961 f.C[b] = setup_malloc!float(f, n4);
962 if (f.A[b] is null || f.B[b] is null || f.C[b] is null) return error(f, STBVorbisError.outofmem);
963 compute_twiddle_factors(n, f.A[b], f.B[b], f.C[b]);
964 f.window[b] = setup_malloc!float(f, n2);
965 if (f.window[b] is null) return error(f, STBVorbisError.outofmem);
966 compute_window(n, f.window[b]);
967 f.bit_reverse[b] = setup_malloc!ushort(f, n8);
968 if (f.bit_reverse[b] is null) return error(f, STBVorbisError.outofmem);
969 compute_bitreverse(n, f.bit_reverse[b]);
970 return true;
973 private void neighbors (ushort* x, int n, ushort* plow, ushort* phigh) {
974 int low = -1;
975 int high = 65536;
976 assert(n >= 0 && n <= ushort.max);
977 foreach (ushort i; 0..cast(ushort)n) {
978 if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; }
979 if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; }
983 // this has been repurposed so y is now the original index instead of y
984 struct Point {
985 ushort x, y;
988 extern(C) int point_compare (const void *p, const void *q) {
989 auto a = cast(const(Point)*)p;
990 auto b = cast(const(Point)*)q;
991 return (a.x < b.x ? -1 : a.x > b.x);
993 /////////////////////// END LEAF SETUP FUNCTIONS //////////////////////////
995 // ///////////////////////////////////////////////////////////////////// //
996 private ubyte get8 (VorbisDecoder f) {
997 ubyte b = void;
998 if (!f.eof) {
999 if (f.rawRead((&b)[0..1]) != 1) { f.eof = true; b = 0; }
1001 return b;
1004 private uint get32 (VorbisDecoder f) {
1005 uint x = 0;
1006 if (!f.eof) {
1007 version(LittleEndian) {
1008 if (f.rawRead((&x)[0..1]) != x.sizeof) { f.eof = true; x = 0; }
1009 } else {
1010 x = get8(f);
1011 x |= cast(uint)get8(f)<<8;
1012 x |= cast(uint)get8(f)<<16;
1013 x |= cast(uint)get8(f)<<24;
1016 return x;
1019 private bool getn (VorbisDecoder f, void* data, int n) {
1020 if (f.eof || n < 0) return false;
1021 if (n == 0) return true;
1022 if (f.rawRead(data[0..n]) != n) { f.eof = true; return false; }
1023 return true;
1026 private void skip (VorbisDecoder f, int n) {
1027 if (f.eof || n <= 0) return;
1028 f.rawSkip(n);
1031 private void set_file_offset (VorbisDecoder f, uint loc) {
1032 /+if (f.push_mode) return;+/
1033 f.eof = false;
1034 if (loc >= 0x80000000) { f.eof = true; return; }
1035 f.rawSeek(loc);
1039 immutable char[4] ogg_page_header = "OggS"; //[ 0x4f, 0x67, 0x67, 0x53 ];
1041 private bool capture_pattern (VorbisDecoder f) {
1042 static if (__VERSION__ > 2067) pragma(inline, true);
1043 char[4] sign = void;
1044 if (!getn(f, sign.ptr, 4)) return false;
1045 return (sign == "OggS");
1048 enum PAGEFLAG_continued_packet = 1;
1049 enum PAGEFLAG_first_page = 2;
1050 enum PAGEFLAG_last_page = 4;
1052 private int start_page_no_capturepattern (VorbisDecoder f) {
1053 uint loc0, loc1, n;
1054 // stream structure version
1055 if (get8(f) != 0) return error(f, STBVorbisError.invalid_stream_structure_version);
1056 // header flag
1057 f.page_flag = get8(f);
1058 // absolute granule position
1059 loc0 = get32(f);
1060 loc1 = get32(f);
1061 // @TODO: validate loc0, loc1 as valid positions?
1062 // stream serial number -- vorbis doesn't interleave, so discard
1063 get32(f);
1064 //if (f.serial != get32(f)) return error(f, STBVorbisError.incorrect_stream_serial_number);
1065 // page sequence number
1066 n = get32(f);
1067 f.last_page = n;
1068 // CRC32
1069 get32(f);
1070 // page_segments
1071 f.segment_count = get8(f);
1072 if (!getn(f, f.segments.ptr, f.segment_count)) return error(f, STBVorbisError.unexpected_eof);
1073 // assume we _don't_ know any the sample position of any segments
1074 f.end_seg_with_known_loc = -2;
1075 if (loc0 != ~0U || loc1 != ~0U) {
1076 int i;
1077 // determine which packet is the last one that will complete
1078 for (i = f.segment_count-1; i >= 0; --i) if (f.segments.ptr[i] < 255) break;
1079 // 'i' is now the index of the _last_ segment of a packet that ends
1080 if (i >= 0) {
1081 f.end_seg_with_known_loc = i;
1082 f.known_loc_for_packet = loc0;
1085 if (f.first_decode) {
1086 int len;
1087 ProbedPage p;
1088 len = 0;
1089 foreach (int i; 0..f.segment_count) len += f.segments.ptr[i];
1090 len += 27+f.segment_count;
1091 p.page_start = f.first_audio_page_offset;
1092 p.page_end = p.page_start+len;
1093 p.last_decoded_sample = loc0;
1094 f.p_first = p;
1096 f.next_seg = 0;
1097 return true;
1100 private int start_page (VorbisDecoder f) {
1101 if (!capture_pattern(f)) return error(f, STBVorbisError.missing_capture_pattern);
1102 return start_page_no_capturepattern(f);
1105 private int start_packet (VorbisDecoder f) {
1106 while (f.next_seg == -1) {
1107 if (!start_page(f)) return false;
1108 if (f.page_flag&PAGEFLAG_continued_packet) return error(f, STBVorbisError.continued_packet_flag_invalid);
1110 f.last_seg = false;
1111 f.valid_bits = 0;
1112 f.packet_bytes = 0;
1113 f.bytes_in_seg = 0;
1114 // f.next_seg is now valid
1115 return true;
1118 private int maybe_start_packet (VorbisDecoder f) {
1119 if (f.next_seg == -1) {
1120 auto x = get8(f);
1121 if (f.eof) return false; // EOF at page boundary is not an error!
1122 if (0x4f != x ) return error(f, STBVorbisError.missing_capture_pattern);
1123 if (0x67 != get8(f)) return error(f, STBVorbisError.missing_capture_pattern);
1124 if (0x67 != get8(f)) return error(f, STBVorbisError.missing_capture_pattern);
1125 if (0x53 != get8(f)) return error(f, STBVorbisError.missing_capture_pattern);
1126 if (!start_page_no_capturepattern(f)) return false;
1127 if (f.page_flag&PAGEFLAG_continued_packet) {
1128 // set up enough state that we can read this packet if we want,
1129 // e.g. during recovery
1130 f.last_seg = false;
1131 f.bytes_in_seg = 0;
1132 return error(f, STBVorbisError.continued_packet_flag_invalid);
1135 return start_packet(f);
1138 private int next_segment (VorbisDecoder f) {
1139 if (f.last_seg) return 0;
1140 if (f.next_seg == -1) {
1141 f.last_seg_which = f.segment_count-1; // in case start_page fails
1142 if (!start_page(f)) { f.last_seg = 1; return 0; }
1143 if (!(f.page_flag&PAGEFLAG_continued_packet)) return error(f, STBVorbisError.continued_packet_flag_invalid);
1145 auto len = f.segments.ptr[f.next_seg++];
1146 if (len < 255) {
1147 f.last_seg = true;
1148 f.last_seg_which = f.next_seg-1;
1150 if (f.next_seg >= f.segment_count) f.next_seg = -1;
1151 debug(stb_vorbis) assert(f.bytes_in_seg == 0);
1152 f.bytes_in_seg = len;
1153 return len;
1156 enum EOP = (-1);
1157 enum INVALID_BITS = (-1);
1159 private int get8_packet_raw (VorbisDecoder f) {
1160 if (!f.bytes_in_seg) { // CLANG!
1161 if (f.last_seg) return EOP;
1162 else if (!next_segment(f)) return EOP;
1164 debug(stb_vorbis) assert(f.bytes_in_seg > 0);
1165 --f.bytes_in_seg;
1166 ++f.packet_bytes;
1167 return get8(f);
1170 private int get8_packet (VorbisDecoder f) {
1171 int x = get8_packet_raw(f);
1172 f.valid_bits = 0;
1173 return x;
1176 private uint get32_packet (VorbisDecoder f) {
1177 uint x = get8_packet(f), b;
1178 if (x == EOP) return EOP;
1179 if ((b = get8_packet(f)) == EOP) return EOP;
1180 x += b<<8;
1181 if ((b = get8_packet(f)) == EOP) return EOP;
1182 x += b<<16;
1183 if ((b = get8_packet(f)) == EOP) return EOP;
1184 x += b<<24;
1185 return x;
1188 private void flush_packet (VorbisDecoder f) {
1189 while (get8_packet_raw(f) != EOP) {}
1192 // @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important
1193 // as the huffman decoder?
1194 private uint get_bits_main (VorbisDecoder f, int n) {
1195 uint z;
1196 if (f.valid_bits < 0) return 0;
1197 if (f.valid_bits < n) {
1198 if (n > 24) {
1199 // the accumulator technique below would not work correctly in this case
1200 z = get_bits_main(f, 24);
1201 z += get_bits_main(f, n-24)<<24;
1202 return z;
1204 if (f.valid_bits == 0) f.acc = 0;
1205 while (f.valid_bits < n) {
1206 z = get8_packet_raw(f);
1207 if (z == EOP) {
1208 f.valid_bits = INVALID_BITS;
1209 return 0;
1211 f.acc += z<<f.valid_bits;
1212 f.valid_bits += 8;
1215 if (f.valid_bits < 0) return 0;
1216 z = f.acc&((1<<n)-1);
1217 f.acc >>= n;
1218 f.valid_bits -= n;
1219 return z;
1222 // chooses minimal possible integer type
1223 private auto get_bits(ubyte n) (VorbisDecoder f) if (n >= 1 && n <= 64) {
1224 static if (n <= 8) return cast(ubyte)get_bits_main(f, n);
1225 else static if (n <= 16) return cast(ushort)get_bits_main(f, n);
1226 else static if (n <= 32) return cast(uint)get_bits_main(f, n);
1227 else static if (n <= 64) return cast(ulong)get_bits_main(f, n);
1228 else static assert(0, "wtf?!");
1231 // chooses minimal possible integer type, assume no overflow
1232 private auto get_bits_add_no(ubyte n) (VorbisDecoder f, ubyte add) if (n >= 1 && n <= 64) {
1233 static if (n <= 8) return cast(ubyte)(get_bits_main(f, n)+add);
1234 else static if (n <= 16) return cast(ushort)(get_bits_main(f, n)+add);
1235 else static if (n <= 32) return cast(uint)(get_bits_main(f, n)+add);
1236 else static if (n <= 64) return cast(ulong)(get_bits_main(f, n)+add);
1237 else static assert(0, "wtf?!");
1240 // @OPTIMIZE: primary accumulator for huffman
1241 // expand the buffer to as many bits as possible without reading off end of packet
1242 // it might be nice to allow f.valid_bits and f.acc to be stored in registers,
1243 // e.g. cache them locally and decode locally
1244 //private /*__forceinline*/ void prep_huffman (VorbisDecoder f)
1245 enum PrepHuffmanMixin = q{
1246 if (f.valid_bits <= 24) {
1247 if (f.valid_bits == 0) f.acc = 0;
1248 int phmz = void;
1249 do {
1250 if (f.last_seg && !f.bytes_in_seg) break;
1251 phmz = get8_packet_raw(f);
1252 if (phmz == EOP) break;
1253 f.acc += cast(uint)phmz<<f.valid_bits;
1254 f.valid_bits += 8;
1255 } while (f.valid_bits <= 24);
1259 enum VorbisPacket {
1260 id = 1,
1261 comment = 3,
1262 setup = 5,
1265 private int codebook_decode_scalar_raw (VorbisDecoder f, Codebook *c) {
1266 mixin(PrepHuffmanMixin);
1268 if (c.codewords is null && c.sorted_codewords is null) return -1;
1269 // cases to use binary search: sorted_codewords && !c.codewords
1270 // sorted_codewords && c.entries > 8
1271 auto cond = (c.entries > 8 ? c.sorted_codewords !is null : !c.codewords);
1272 if (cond) {
1273 // binary search
1274 uint code = bit_reverse(f.acc);
1275 int x = 0, n = c.sorted_entries, len;
1276 while (n > 1) {
1277 // invariant: sc[x] <= code < sc[x+n]
1278 int m = x+(n>>1);
1279 if (c.sorted_codewords[m] <= code) {
1280 x = m;
1281 n -= (n>>1);
1282 } else {
1283 n >>= 1;
1286 // x is now the sorted index
1287 if (!c.sparse) x = c.sorted_values[x];
1288 // x is now sorted index if sparse, or symbol otherwise
1289 len = c.codeword_lengths[x];
1290 if (f.valid_bits >= len) {
1291 f.acc >>= len;
1292 f.valid_bits -= len;
1293 return x;
1295 f.valid_bits = 0;
1296 return -1;
1298 // if small, linear search
1299 debug(stb_vorbis) assert(!c.sparse);
1300 foreach (uint i; 0..c.entries) {
1301 if (c.codeword_lengths[i] == NO_CODE) continue;
1302 if (c.codewords[i] == (f.acc&((1<<c.codeword_lengths[i])-1))) {
1303 if (f.valid_bits >= c.codeword_lengths[i]) {
1304 f.acc >>= c.codeword_lengths[i];
1305 f.valid_bits -= c.codeword_lengths[i];
1306 return i;
1308 f.valid_bits = 0;
1309 return -1;
1312 error(f, STBVorbisError.invalid_stream);
1313 f.valid_bits = 0;
1314 return -1;
1318 template DECODE_RAW(string var, string c) {
1319 enum DECODE_RAW = q{
1320 if (f.valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) { mixin(PrepHuffmanMixin); }
1321 // fast huffman table lookup
1322 ${i} = f.acc&FAST_HUFFMAN_TABLE_MASK;
1323 ${i} = ${c}.fast_huffman.ptr[${i}];
1324 if (${i} >= 0) {
1325 auto ${__temp_prefix__}n = ${c}.codeword_lengths[${i}];
1326 f.acc >>= ${__temp_prefix__}n;
1327 f.valid_bits -= ${__temp_prefix__}n;
1328 if (f.valid_bits < 0) { f.valid_bits = 0; ${i} = -1; }
1329 } else {
1330 ${i} = codebook_decode_scalar_raw(f, ${c});
1332 }.cmacroFixVars!("i", "c")(var, c);
1335 enum DECODE(string var, string c) = q{
1336 ${DECODE_RAW}
1337 if (${c}.sparse) ${var} = ${c}.sorted_values[${var}];
1338 }.cmacroFixVars!("var", "c", "DECODE_RAW")(var, c, DECODE_RAW!(var, c));
1341 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {
1342 alias DECODE_VQ = DECODE;
1343 } else {
1344 alias DECODE_VQ = DECODE_RAW;
1349 // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case
1350 // where we avoid one addition
1351 enum CODEBOOK_ELEMENT(string c, string off) = "("~c~".multiplicands["~off~"])";
1352 enum CODEBOOK_ELEMENT_FAST(string c, string off) = "("~c~".multiplicands["~off~"])";
1353 enum CODEBOOK_ELEMENT_BASE(string c) = "(0)";
1356 private int codebook_decode_start (VorbisDecoder f, Codebook* c) {
1357 int z = -1;
1358 // type 0 is only legal in a scalar context
1359 if (c.lookup_type == 0) {
1360 error(f, STBVorbisError.invalid_stream);
1361 } else {
1362 mixin(DECODE_VQ!("z", "c"));
1363 debug(stb_vorbis) if (c.sparse) assert(z < c.sorted_entries);
1364 if (z < 0) { // check for EOP
1365 if (!f.bytes_in_seg && f.last_seg) return z;
1366 error(f, STBVorbisError.invalid_stream);
1369 return z;
1372 private int codebook_decode (VorbisDecoder f, Codebook* c, float* output, int len) {
1373 int z = codebook_decode_start(f, c);
1374 if (z < 0) return false;
1375 if (len > c.dimensions) len = c.dimensions;
1377 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {
1378 if (c.lookup_type == 1) {
1379 float last = mixin(CODEBOOK_ELEMENT_BASE!"c");
1380 int div = 1;
1381 foreach (immutable i; 0..len) {
1382 int off = (z/div)%c.lookup_values;
1383 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "off"))+last;
1384 output[i] += val;
1385 if (c.sequence_p) last = val+c.minimum_value;
1386 div *= c.lookup_values;
1388 return true;
1392 z *= c.dimensions;
1393 if (c.sequence_p) {
1394 float last = mixin(CODEBOOK_ELEMENT_BASE!"c");
1395 foreach (immutable i; 0..len) {
1396 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "z+i"))+last;
1397 output[i] += val;
1398 last = val+c.minimum_value;
1400 } else {
1401 float last = mixin(CODEBOOK_ELEMENT_BASE!"c");
1402 foreach (immutable i; 0..len) output[i] += mixin(CODEBOOK_ELEMENT_FAST!("c", "z+i"))+last;
1405 return true;
1408 private int codebook_decode_step (VorbisDecoder f, Codebook* c, float* output, int len, int step) {
1409 int z = codebook_decode_start(f, c);
1410 float last = mixin(CODEBOOK_ELEMENT_BASE!"c");
1411 if (z < 0) return false;
1412 if (len > c.dimensions) len = c.dimensions;
1414 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {
1415 if (c.lookup_type == 1) {
1416 int div = 1;
1417 foreach (immutable i; 0..len) {
1418 int off = (z/div)%c.lookup_values;
1419 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "off"))+last;
1420 output[i*step] += val;
1421 if (c.sequence_p) last = val;
1422 div *= c.lookup_values;
1424 return true;
1428 z *= c.dimensions;
1429 foreach (immutable i; 0..len) {
1430 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "z+i"))+last;
1431 output[i*step] += val;
1432 if (c.sequence_p) last = val;
1435 return true;
1438 private int codebook_decode_deinterleave_repeat (VorbisDecoder f, Codebook* c, ref float*[STB_VORBIS_MAX_CHANNELS] outputs, int ch, int* c_inter_p, int* p_inter_p, int len, int total_decode) {
1439 int c_inter = *c_inter_p;
1440 int p_inter = *p_inter_p;
1441 int z, effective = c.dimensions;
1443 // type 0 is only legal in a scalar context
1444 if (c.lookup_type == 0) return error(f, STBVorbisError.invalid_stream);
1446 while (total_decode > 0) {
1447 float last = mixin(CODEBOOK_ELEMENT_BASE!"c");
1448 mixin(DECODE_VQ!("z", "c"));
1449 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {} else {
1450 debug(stb_vorbis) assert(!c.sparse || z < c.sorted_entries);
1452 if (z < 0) {
1453 if (!f.bytes_in_seg && f.last_seg) return false;
1454 return error(f, STBVorbisError.invalid_stream);
1457 // if this will take us off the end of the buffers, stop short!
1458 // we check by computing the length of the virtual interleaved
1459 // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter),
1460 // and the length we'll be using (effective)
1461 if (c_inter+p_inter*ch+effective > len*ch) effective = len*ch-(p_inter*ch-c_inter);
1463 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {
1464 if (c.lookup_type == 1) {
1465 int div = 1;
1466 foreach (immutable i; 0..effective) {
1467 int off = (z/div)%c.lookup_values;
1468 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "off"))+last;
1469 if (outputs.ptr[c_inter]) outputs.ptr[c_inter].ptr[p_inter] += val;
1470 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
1471 if (c.sequence_p) last = val;
1472 div *= c.lookup_values;
1474 goto skipit;
1477 z *= c.dimensions;
1478 if (c.sequence_p) {
1479 foreach (immutable i; 0..effective) {
1480 float val = mixin(CODEBOOK_ELEMENT_FAST!("c", "z+i"))+last;
1481 if (outputs.ptr[c_inter]) outputs.ptr[c_inter][p_inter] += val;
1482 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
1483 last = val;
1485 } else {
1486 foreach (immutable i; 0..effective) {
1487 float val = mixin(CODEBOOK_ELEMENT_FAST!("c","z+i"))+last;
1488 if (outputs.ptr[c_inter]) outputs.ptr[c_inter][p_inter] += val;
1489 if (++c_inter == ch) { c_inter = 0; ++p_inter; }
1492 skipit:
1493 total_decode -= effective;
1495 *c_inter_p = c_inter;
1496 *p_inter_p = p_inter;
1497 return true;
1500 //private int predict_point (int x, int x0, int x1, int y0, int y1)
1501 enum predict_point(string dest, string x, string x0, string x1, string y0, string y1) = q{{
1502 //import std.math : abs;
1503 int dy = ${y1}-${y0};
1504 int adx = ${x1}-${x0};
1505 // @OPTIMIZE: force int division to round in the right direction... is this necessary on x86?
1506 int err = /*abs(dy)*/(dy < 0 ? -dy : dy)*(${x}-${x0});
1507 int off = err/adx;
1508 /*return*/${dest} = (dy < 0 ? ${y0}-off : ${y0}+off);
1509 }}.cmacroFixVars!("dest", "x", "x0", "x1", "y0", "y1")(dest, x, x0, x1, y0, y1);
1511 // the following table is block-copied from the specification
1512 immutable float[256] inverse_db_table = [
1513 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f,
1514 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
1515 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f,
1516 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f,
1517 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f,
1518 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f,
1519 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f,
1520 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f,
1521 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f,
1522 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f,
1523 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f,
1524 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f,
1525 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f,
1526 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f,
1527 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f,
1528 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f,
1529 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f,
1530 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f,
1531 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f,
1532 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f,
1533 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f,
1534 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f,
1535 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f,
1536 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f,
1537 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f,
1538 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f,
1539 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f,
1540 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f,
1541 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f,
1542 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f,
1543 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f,
1544 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f,
1545 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f,
1546 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f,
1547 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f,
1548 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f,
1549 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f,
1550 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f,
1551 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f,
1552 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f,
1553 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f,
1554 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f,
1555 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f,
1556 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f,
1557 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f,
1558 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f,
1559 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f,
1560 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f,
1561 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f,
1562 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f,
1563 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f,
1564 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f,
1565 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f,
1566 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f,
1567 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f,
1568 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f,
1569 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f,
1570 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f,
1571 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f,
1572 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f,
1573 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f,
1574 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f,
1575 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f,
1576 0.82788260f, 0.88168307f, 0.9389798f, 1.0f
1580 // @OPTIMIZE: if you want to replace this bresenham line-drawing routine,
1581 // note that you must produce bit-identical output to decode correctly;
1582 // this specific sequence of operations is specified in the spec (it's
1583 // drawing integer-quantized frequency-space lines that the encoder
1584 // expects to be exactly the same)
1585 // ... also, isn't the whole point of Bresenham's algorithm to NOT
1586 // have to divide in the setup? sigh.
1587 version(STB_VORBIS_NO_DEFER_FLOOR) {
1588 enum LINE_OP(string a, string b) = a~" = "~b~";";
1589 } else {
1590 enum LINE_OP(string a, string b) = a~" *= "~b~";";
1593 version(STB_VORBIS_DIVIDE_TABLE) {
1594 enum DIVTAB_NUMER = 32;
1595 enum DIVTAB_DENOM = 64;
1596 byte[DIVTAB_DENOM][DIVTAB_NUMER] integer_divide_table; // 2KB
1599 // nobranch abs trick
1600 enum ABS(string v) = q{(((${v})+((${v})>>31))^((${v})>>31))}.cmacroFixVars!"v"(v);
1602 // this is forceinline, but dmd inliner sux
1603 // but hey, i have my k00l macrosystem!
1604 //void draw_line (float* ${output}, int ${x0}, int ${y0}, int ${x1}, int ${y1}, int ${n})
1605 enum draw_line(string output, string x0, string y0, string x1, string y1, string n) = q{{
1606 int ${__temp_prefix__}dy = ${y1}-${y0};
1607 int ${__temp_prefix__}adx = ${x1}-${x0};
1608 int ${__temp_prefix__}ady = mixin(ABS!"${__temp_prefix__}dy");
1609 int ${__temp_prefix__}base;
1610 int ${__temp_prefix__}x = ${x0}, ${__temp_prefix__}y = ${y0};
1611 int ${__temp_prefix__}err = 0;
1612 int ${__temp_prefix__}sy;
1614 version(STB_VORBIS_DIVIDE_TABLE) {
1615 if (${__temp_prefix__}adx < DIVTAB_DENOM && ${__temp_prefix__}ady < DIVTAB_NUMER) {
1616 if (${__temp_prefix__}dy < 0) {
1617 ${__temp_prefix__}base = -integer_divide_table[${__temp_prefix__}ady].ptr[${__temp_prefix__}adx];
1618 ${__temp_prefix__}sy = ${__temp_prefix__}base-1;
1619 } else {
1620 ${__temp_prefix__}base = integer_divide_table[${__temp_prefix__}ady].ptr[${__temp_prefix__}adx];
1621 ${__temp_prefix__}sy = ${__temp_prefix__}base+1;
1623 } else {
1624 ${__temp_prefix__}base = ${__temp_prefix__}dy/${__temp_prefix__}adx;
1625 ${__temp_prefix__}sy = ${__temp_prefix__}base+(${__temp_prefix__}dy < 0 ? -1 : 1);
1627 } else {
1628 ${__temp_prefix__}base = ${__temp_prefix__}dy/${__temp_prefix__}adx;
1629 ${__temp_prefix__}sy = ${__temp_prefix__}base+(${__temp_prefix__}dy < 0 ? -1 : 1);
1631 ${__temp_prefix__}ady -= mixin(ABS!"${__temp_prefix__}base")*${__temp_prefix__}adx;
1632 if (${x1} > ${n}) ${x1} = ${n};
1633 if (${__temp_prefix__}x < ${x1}) {
1634 mixin(LINE_OP!("${output}[${__temp_prefix__}x]", "inverse_db_table[${__temp_prefix__}y]"));
1635 for (++${__temp_prefix__}x; ${__temp_prefix__}x < ${x1}; ++${__temp_prefix__}x) {
1636 ${__temp_prefix__}err += ${__temp_prefix__}ady;
1637 if (${__temp_prefix__}err >= ${__temp_prefix__}adx) {
1638 ${__temp_prefix__}err -= ${__temp_prefix__}adx;
1639 ${__temp_prefix__}y += ${__temp_prefix__}sy;
1640 } else {
1641 ${__temp_prefix__}y += ${__temp_prefix__}base;
1643 mixin(LINE_OP!("${output}[${__temp_prefix__}x]", "inverse_db_table[${__temp_prefix__}y]"));
1647 mixin(LINE_OP!("${output}[${__temp_prefix__}x]", "inverse_db_table[${__temp_prefix__}y]"));
1648 for (++${__temp_prefix__}x; ${__temp_prefix__}x < ${x1}; ++${__temp_prefix__}x) {
1649 ${__temp_prefix__}err += ${__temp_prefix__}ady;
1650 if (${__temp_prefix__}err >= ${__temp_prefix__}adx) {
1651 ${__temp_prefix__}err -= ${__temp_prefix__}adx;
1652 ${__temp_prefix__}y += ${__temp_prefix__}sy;
1653 } else {
1654 ${__temp_prefix__}y += ${__temp_prefix__}base;
1656 mixin(LINE_OP!("${output}[${__temp_prefix__}x]", "inverse_db_table[${__temp_prefix__}y]"));
1659 }}.cmacroFixVars!("output", "x0", "y0", "x1", "y1", "n")(output, x0, y0, x1, y1, n);
1661 private int residue_decode (VorbisDecoder f, Codebook* book, float* target, int offset, int n, int rtype) {
1662 if (rtype == 0) {
1663 int step = n/book.dimensions;
1664 foreach (immutable k; 0..step) if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) return false;
1665 } else {
1666 for (int k = 0; k < n; ) {
1667 if (!codebook_decode(f, book, target+offset, n-k)) return false;
1668 k += book.dimensions;
1669 offset += book.dimensions;
1672 return true;
1675 private void decode_residue (VorbisDecoder f, ref float*[STB_VORBIS_MAX_CHANNELS] residue_buffers, int ch, int n, int rn, ubyte* do_not_decode) {
1676 import core.stdc.stdlib : alloca;
1677 import core.stdc.string : memset;
1679 Residue* r = f.residue_config+rn;
1680 int rtype = f.residue_types.ptr[rn];
1681 int c = r.classbook;
1682 int classwords = f.codebooks[c].dimensions;
1683 int n_read = r.end-r.begin;
1684 int part_read = n_read/r.part_size;
1685 uint temp_alloc_point = temp_alloc_save(f);
1686 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1687 int** classifications = cast(int**)mixin(temp_block_array!("f.vrchannels", "part_read*int.sizeof"));
1688 } else {
1689 ubyte*** part_classdata = cast(ubyte***)mixin(temp_block_array!("f.vrchannels", "part_read*cast(int)(ubyte*).sizeof"));
1692 //stb_prof(2);
1693 foreach (immutable i; 0..ch) if (!do_not_decode[i]) memset(residue_buffers.ptr[i], 0, float.sizeof*n);
1695 if (rtype == 2 && ch != 1) {
1696 int j = void;
1697 for (j = 0; j < ch; ++j) if (!do_not_decode[j]) break;
1698 if (j == ch) goto done;
1700 //stb_prof(3);
1701 foreach (immutable pass; 0..8) {
1702 int pcount = 0, class_set = 0;
1703 if (ch == 2) {
1704 //stb_prof(13);
1705 while (pcount < part_read) {
1706 int z = r.begin+pcount*r.part_size;
1707 int c_inter = (z&1), p_inter = z>>1;
1708 if (pass == 0) {
1709 Codebook *cc = f.codebooks+r.classbook;
1710 int q;
1711 mixin(DECODE!("q", "cc"));
1712 if (q == EOP) goto done;
1713 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1714 for (int i = classwords-1; i >= 0; --i) {
1715 classifications[0].ptr[i+pcount] = q%r.classifications;
1716 q /= r.classifications;
1718 } else {
1719 part_classdata[0][class_set] = r.classdata[q];
1722 //stb_prof(5);
1723 for (int i = 0; i < classwords && pcount < part_read; ++i, ++pcount) {
1724 int zz = r.begin+pcount*r.part_size;
1725 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1726 int cc = classifications[0].ptr[pcount];
1727 } else {
1728 int cc = part_classdata[0][class_set][i];
1730 int b = r.residue_books[cc].ptr[pass];
1731 if (b >= 0) {
1732 Codebook* book = f.codebooks+b;
1733 //stb_prof(20); // accounts for X time
1734 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {
1735 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r.part_size)) goto done;
1736 } else {
1737 // saves 1%
1738 //if (!codebook_decode_deinterleave_repeat_2(f, book, residue_buffers, &c_inter, &p_inter, n, r.part_size)) goto done; // according to C source
1739 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r.part_size)) goto done;
1741 //stb_prof(7);
1742 } else {
1743 zz += r.part_size;
1744 c_inter = zz&1;
1745 p_inter = zz>>1;
1748 //stb_prof(8);
1749 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {} else {
1750 ++class_set;
1753 } else if (ch == 1) {
1754 while (pcount < part_read) {
1755 int z = r.begin+pcount*r.part_size;
1756 int c_inter = 0, p_inter = z;
1757 if (pass == 0) {
1758 Codebook* cc = f.codebooks+r.classbook;
1759 int q;
1760 mixin(DECODE!("q", "cc"));
1761 if (q == EOP) goto done;
1762 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1763 for (int i = classwords-1; i >= 0; --i) {
1764 classifications[0].ptr[i+pcount] = q%r.classifications;
1765 q /= r.classifications;
1767 } else {
1768 part_classdata[0][class_set] = r.classdata[q];
1771 for (int i = 0; i < classwords && pcount < part_read; ++i, ++pcount) {
1772 int zz = r.begin+pcount*r.part_size;
1773 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1774 int cc = classifications[0].ptr[pcount];
1775 } else {
1776 int cc = part_classdata[0][class_set][i];
1778 int b = r.residue_books[cc].ptr[pass];
1779 if (b >= 0) {
1780 Codebook* book = f.codebooks+b;
1781 //stb_prof(22);
1782 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r.part_size)) goto done;
1783 //stb_prof(3);
1784 } else {
1785 zz += r.part_size;
1786 c_inter = 0;
1787 p_inter = zz;
1790 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {} else {
1791 ++class_set;
1794 } else {
1795 while (pcount < part_read) {
1796 int z = r.begin+pcount*r.part_size;
1797 int c_inter = z%ch, p_inter = z/ch;
1798 if (pass == 0) {
1799 Codebook* cc = f.codebooks+r.classbook;
1800 int q;
1801 mixin(DECODE!("q", "cc"));
1802 if (q == EOP) goto done;
1803 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1804 for (int i = classwords-1; i >= 0; --i) {
1805 classifications[0].ptr[i+pcount] = q%r.classifications;
1806 q /= r.classifications;
1808 } else {
1809 part_classdata[0][class_set] = r.classdata[q];
1812 for (int i = 0; i < classwords && pcount < part_read; ++i, ++pcount) {
1813 int zz = r.begin+pcount*r.part_size;
1814 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1815 int cc = classifications[0].ptr[pcount];
1816 } else {
1817 int cc = part_classdata[0][class_set][i];
1819 int b = r.residue_books[cc].ptr[pass];
1820 if (b >= 0) {
1821 Codebook* book = f.codebooks+b;
1822 //stb_prof(22);
1823 if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r.part_size)) goto done;
1824 //stb_prof(3);
1825 } else {
1826 zz += r.part_size;
1827 c_inter = zz%ch;
1828 p_inter = zz/ch;
1831 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {} else {
1832 ++class_set;
1837 goto done;
1839 //stb_prof(9);
1841 foreach (immutable pass; 0..8) {
1842 int pcount = 0, class_set=0;
1843 while (pcount < part_read) {
1844 if (pass == 0) {
1845 foreach (immutable j; 0..ch) {
1846 if (!do_not_decode[j]) {
1847 Codebook* cc = f.codebooks+r.classbook;
1848 int temp;
1849 mixin(DECODE!("temp", "cc"));
1850 if (temp == EOP) goto done;
1851 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1852 for (int i = classwords-1; i >= 0; --i) {
1853 classifications[j].ptr[i+pcount] = temp%r.classifications;
1854 temp /= r.classifications;
1856 } else {
1857 part_classdata[j][class_set] = r.classdata[temp];
1862 for (int i = 0; i < classwords && pcount < part_read; ++i, ++pcount) {
1863 foreach (immutable j; 0..ch) {
1864 if (!do_not_decode[j]) {
1865 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
1866 int cc = classifications[j].ptr[pcount];
1867 } else {
1868 int cc = part_classdata[j][class_set][i];
1870 int b = r.residue_books[cc].ptr[pass];
1871 if (b >= 0) {
1872 float* target = residue_buffers.ptr[j];
1873 int offset = r.begin+pcount*r.part_size;
1874 int nn = r.part_size;
1875 Codebook* book = f.codebooks+b;
1876 if (!residue_decode(f, book, target, offset, nn, rtype)) goto done;
1881 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {} else {
1882 ++class_set;
1886 done:
1887 //stb_prof(0);
1888 version(STB_VORBIS_DIVIDES_IN_RESIDUE) temp_free(f, classifications); else temp_free(f, part_classdata);
1889 temp_alloc_restore(f, temp_alloc_point);
1893 // the following were split out into separate functions while optimizing;
1894 // they could be pushed back up but eh. __forceinline showed no change;
1895 // they're probably already being inlined.
1896 private void imdct_step3_iter0_loop (int n, float* e, int i_off, int k_off, float* A) {
1897 float* ee0 = e+i_off;
1898 float* ee2 = ee0+k_off;
1899 debug(stb_vorbis) assert((n&3) == 0);
1900 foreach (immutable _; 0..n>>2) {
1901 float k00_20, k01_21;
1902 k00_20 = ee0[ 0]-ee2[ 0];
1903 k01_21 = ee0[-1]-ee2[-1];
1904 ee0[ 0] += ee2[ 0];//ee0[ 0] = ee0[ 0]+ee2[ 0];
1905 ee0[-1] += ee2[-1];//ee0[-1] = ee0[-1]+ee2[-1];
1906 ee2[ 0] = k00_20*A[0]-k01_21*A[1];
1907 ee2[-1] = k01_21*A[0]+k00_20*A[1];
1908 A += 8;
1910 k00_20 = ee0[-2]-ee2[-2];
1911 k01_21 = ee0[-3]-ee2[-3];
1912 ee0[-2] += ee2[-2];//ee0[-2] = ee0[-2]+ee2[-2];
1913 ee0[-3] += ee2[-3];//ee0[-3] = ee0[-3]+ee2[-3];
1914 ee2[-2] = k00_20*A[0]-k01_21*A[1];
1915 ee2[-3] = k01_21*A[0]+k00_20*A[1];
1916 A += 8;
1918 k00_20 = ee0[-4]-ee2[-4];
1919 k01_21 = ee0[-5]-ee2[-5];
1920 ee0[-4] += ee2[-4];//ee0[-4] = ee0[-4]+ee2[-4];
1921 ee0[-5] += ee2[-5];//ee0[-5] = ee0[-5]+ee2[-5];
1922 ee2[-4] = k00_20*A[0]-k01_21*A[1];
1923 ee2[-5] = k01_21*A[0]+k00_20*A[1];
1924 A += 8;
1926 k00_20 = ee0[-6]-ee2[-6];
1927 k01_21 = ee0[-7]-ee2[-7];
1928 ee0[-6] += ee2[-6];//ee0[-6] = ee0[-6]+ee2[-6];
1929 ee0[-7] += ee2[-7];//ee0[-7] = ee0[-7]+ee2[-7];
1930 ee2[-6] = k00_20*A[0]-k01_21*A[1];
1931 ee2[-7] = k01_21*A[0]+k00_20*A[1];
1932 A += 8;
1933 ee0 -= 8;
1934 ee2 -= 8;
1938 private void imdct_step3_inner_r_loop (int lim, float* e, int d0, int k_off, float* A, int k1) {
1939 float k00_20, k01_21;
1940 float* e0 = e+d0;
1941 float* e2 = e0+k_off;
1942 foreach (immutable _; 0..lim>>2) {
1943 k00_20 = e0[-0]-e2[-0];
1944 k01_21 = e0[-1]-e2[-1];
1945 e0[-0] += e2[-0];//e0[-0] = e0[-0]+e2[-0];
1946 e0[-1] += e2[-1];//e0[-1] = e0[-1]+e2[-1];
1947 e2[-0] = (k00_20)*A[0]-(k01_21)*A[1];
1948 e2[-1] = (k01_21)*A[0]+(k00_20)*A[1];
1950 A += k1;
1952 k00_20 = e0[-2]-e2[-2];
1953 k01_21 = e0[-3]-e2[-3];
1954 e0[-2] += e2[-2];//e0[-2] = e0[-2]+e2[-2];
1955 e0[-3] += e2[-3];//e0[-3] = e0[-3]+e2[-3];
1956 e2[-2] = (k00_20)*A[0]-(k01_21)*A[1];
1957 e2[-3] = (k01_21)*A[0]+(k00_20)*A[1];
1959 A += k1;
1961 k00_20 = e0[-4]-e2[-4];
1962 k01_21 = e0[-5]-e2[-5];
1963 e0[-4] += e2[-4];//e0[-4] = e0[-4]+e2[-4];
1964 e0[-5] += e2[-5];//e0[-5] = e0[-5]+e2[-5];
1965 e2[-4] = (k00_20)*A[0]-(k01_21)*A[1];
1966 e2[-5] = (k01_21)*A[0]+(k00_20)*A[1];
1968 A += k1;
1970 k00_20 = e0[-6]-e2[-6];
1971 k01_21 = e0[-7]-e2[-7];
1972 e0[-6] += e2[-6];//e0[-6] = e0[-6]+e2[-6];
1973 e0[-7] += e2[-7];//e0[-7] = e0[-7]+e2[-7];
1974 e2[-6] = (k00_20)*A[0]-(k01_21)*A[1];
1975 e2[-7] = (k01_21)*A[0]+(k00_20)*A[1];
1977 e0 -= 8;
1978 e2 -= 8;
1980 A += k1;
1984 private void imdct_step3_inner_s_loop (int n, float* e, int i_off, int k_off, float* A, int a_off, int k0) {
1985 float A0 = A[0];
1986 float A1 = A[0+1];
1987 float A2 = A[0+a_off];
1988 float A3 = A[0+a_off+1];
1989 float A4 = A[0+a_off*2+0];
1990 float A5 = A[0+a_off*2+1];
1991 float A6 = A[0+a_off*3+0];
1992 float A7 = A[0+a_off*3+1];
1993 float k00, k11;
1994 float *ee0 = e +i_off;
1995 float *ee2 = ee0+k_off;
1996 foreach (immutable _; 0..n) {
1997 k00 = ee0[ 0]-ee2[ 0];
1998 k11 = ee0[-1]-ee2[-1];
1999 ee0[ 0] = ee0[ 0]+ee2[ 0];
2000 ee0[-1] = ee0[-1]+ee2[-1];
2001 ee2[ 0] = (k00)*A0-(k11)*A1;
2002 ee2[-1] = (k11)*A0+(k00)*A1;
2004 k00 = ee0[-2]-ee2[-2];
2005 k11 = ee0[-3]-ee2[-3];
2006 ee0[-2] = ee0[-2]+ee2[-2];
2007 ee0[-3] = ee0[-3]+ee2[-3];
2008 ee2[-2] = (k00)*A2-(k11)*A3;
2009 ee2[-3] = (k11)*A2+(k00)*A3;
2011 k00 = ee0[-4]-ee2[-4];
2012 k11 = ee0[-5]-ee2[-5];
2013 ee0[-4] = ee0[-4]+ee2[-4];
2014 ee0[-5] = ee0[-5]+ee2[-5];
2015 ee2[-4] = (k00)*A4-(k11)*A5;
2016 ee2[-5] = (k11)*A4+(k00)*A5;
2018 k00 = ee0[-6]-ee2[-6];
2019 k11 = ee0[-7]-ee2[-7];
2020 ee0[-6] = ee0[-6]+ee2[-6];
2021 ee0[-7] = ee0[-7]+ee2[-7];
2022 ee2[-6] = (k00)*A6-(k11)*A7;
2023 ee2[-7] = (k11)*A6+(k00)*A7;
2025 ee0 -= k0;
2026 ee2 -= k0;
2030 // this was forceinline
2031 //void iter_54(float *z)
2032 enum iter_54(string z) = q{{
2033 auto ${__temp_prefix__}z = (${z});
2034 float ${__temp_prefix__}k00, ${__temp_prefix__}k11, ${__temp_prefix__}k22, ${__temp_prefix__}k33;
2035 float ${__temp_prefix__}y0, ${__temp_prefix__}y1, ${__temp_prefix__}y2, ${__temp_prefix__}y3;
2037 ${__temp_prefix__}k00 = ${__temp_prefix__}z[ 0]-${__temp_prefix__}z[-4];
2038 ${__temp_prefix__}y0 = ${__temp_prefix__}z[ 0]+${__temp_prefix__}z[-4];
2039 ${__temp_prefix__}y2 = ${__temp_prefix__}z[-2]+${__temp_prefix__}z[-6];
2040 ${__temp_prefix__}k22 = ${__temp_prefix__}z[-2]-${__temp_prefix__}z[-6];
2042 ${__temp_prefix__}z[-0] = ${__temp_prefix__}y0+${__temp_prefix__}y2; // z0+z4+z2+z6
2043 ${__temp_prefix__}z[-2] = ${__temp_prefix__}y0-${__temp_prefix__}y2; // z0+z4-z2-z6
2045 // done with ${__temp_prefix__}y0, ${__temp_prefix__}y2
2047 ${__temp_prefix__}k33 = ${__temp_prefix__}z[-3]-${__temp_prefix__}z[-7];
2049 ${__temp_prefix__}z[-4] = ${__temp_prefix__}k00+${__temp_prefix__}k33; // z0-z4+z3-z7
2050 ${__temp_prefix__}z[-6] = ${__temp_prefix__}k00-${__temp_prefix__}k33; // z0-z4-z3+z7
2052 // done with ${__temp_prefix__}k33
2054 ${__temp_prefix__}k11 = ${__temp_prefix__}z[-1]-${__temp_prefix__}z[-5];
2055 ${__temp_prefix__}y1 = ${__temp_prefix__}z[-1]+${__temp_prefix__}z[-5];
2056 ${__temp_prefix__}y3 = ${__temp_prefix__}z[-3]+${__temp_prefix__}z[-7];
2058 ${__temp_prefix__}z[-1] = ${__temp_prefix__}y1+${__temp_prefix__}y3; // z1+z5+z3+z7
2059 ${__temp_prefix__}z[-3] = ${__temp_prefix__}y1-${__temp_prefix__}y3; // z1+z5-z3-z7
2060 ${__temp_prefix__}z[-5] = ${__temp_prefix__}k11-${__temp_prefix__}k22; // z1-z5+z2-z6
2061 ${__temp_prefix__}z[-7] = ${__temp_prefix__}k11+${__temp_prefix__}k22; // z1-z5-z2+z6
2062 }}.cmacroFixVars!"z"(z);
2064 private void imdct_step3_inner_s_loop_ld654 (int n, float* e, int i_off, float* A, int base_n) {
2065 int a_off = base_n>>3;
2066 float A2 = A[0+a_off];
2067 float* z = e+i_off;
2068 float* base = z-16*n;
2069 float k00, k11;
2070 while (z > base) {
2071 k00 = z[-0]-z[-8];
2072 k11 = z[-1]-z[-9];
2073 z[-0] = z[-0]+z[-8];
2074 z[-1] = z[-1]+z[-9];
2075 z[-8] = k00;
2076 z[-9] = k11;
2078 k00 = z[ -2]-z[-10];
2079 k11 = z[ -3]-z[-11];
2080 z[ -2] = z[ -2]+z[-10];
2081 z[ -3] = z[ -3]+z[-11];
2082 z[-10] = (k00+k11)*A2;
2083 z[-11] = (k11-k00)*A2;
2085 k00 = z[-12]-z[ -4]; // reverse to avoid a unary negation
2086 k11 = z[ -5]-z[-13];
2087 z[ -4] = z[ -4]+z[-12];
2088 z[ -5] = z[ -5]+z[-13];
2089 z[-12] = k11;
2090 z[-13] = k00;
2092 k00 = z[-14]-z[ -6]; // reverse to avoid a unary negation
2093 k11 = z[ -7]-z[-15];
2094 z[ -6] = z[ -6]+z[-14];
2095 z[ -7] = z[ -7]+z[-15];
2096 z[-14] = (k00+k11)*A2;
2097 z[-15] = (k00-k11)*A2;
2099 mixin(iter_54!"z");
2100 mixin(iter_54!"z-8");
2101 z -= 16;
2105 private void inverse_mdct (float* buffer, int n, VorbisDecoder f, int blocktype) {
2106 import core.stdc.stdlib : alloca;
2108 int n2 = n>>1, n4 = n>>2, n8 = n>>3, l;
2109 int ld;
2110 // @OPTIMIZE: reduce register pressure by using fewer variables?
2111 int save_point = temp_alloc_save(f);
2112 float *buf2;
2113 buf2 = cast(float*)mixin(temp_alloc!("n2*float.sizeof"));
2114 float *u = null, v = null;
2115 // twiddle factors
2116 float *A = f.A.ptr[blocktype];
2118 // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio"
2119 // See notes about bugs in that paper in less-optimal implementation 'inverse_mdct_old' after this function.
2121 // kernel from paper
2124 // merged:
2125 // copy and reflect spectral data
2126 // step 0
2128 // note that it turns out that the items added together during
2129 // this step are, in fact, being added to themselves (as reflected
2130 // by step 0). inexplicable inefficiency! this became obvious
2131 // once I combined the passes.
2133 // so there's a missing 'times 2' here (for adding X to itself).
2134 // this propogates through linearly to the end, where the numbers
2135 // are 1/2 too small, and need to be compensated for.
2138 float* d, e, AA, e_stop;
2139 d = &buf2[n2-2];
2140 AA = A;
2141 e = &buffer[0];
2142 e_stop = &buffer[n2];
2143 while (e != e_stop) {
2144 d[1] = (e[0]*AA[0]-e[2]*AA[1]);
2145 d[0] = (e[0]*AA[1]+e[2]*AA[0]);
2146 d -= 2;
2147 AA += 2;
2148 e += 4;
2150 e = &buffer[n2-3];
2151 while (d >= buf2) {
2152 d[1] = (-e[2]*AA[0]- -e[0]*AA[1]);
2153 d[0] = (-e[2]*AA[1]+ -e[0]*AA[0]);
2154 d -= 2;
2155 AA += 2;
2156 e -= 4;
2160 // now we use symbolic names for these, so that we can
2161 // possibly swap their meaning as we change which operations
2162 // are in place
2164 u = buffer;
2165 v = buf2;
2167 // step 2 (paper output is w, now u)
2168 // this could be in place, but the data ends up in the wrong
2169 // place... _somebody_'s got to swap it, so this is nominated
2171 float* AA = &A[n2-8];
2172 float* d0, d1, e0, e1;
2173 e0 = &v[n4];
2174 e1 = &v[0];
2175 d0 = &u[n4];
2176 d1 = &u[0];
2177 while (AA >= A) {
2178 float v40_20, v41_21;
2180 v41_21 = e0[1]-e1[1];
2181 v40_20 = e0[0]-e1[0];
2182 d0[1] = e0[1]+e1[1];
2183 d0[0] = e0[0]+e1[0];
2184 d1[1] = v41_21*AA[4]-v40_20*AA[5];
2185 d1[0] = v40_20*AA[4]+v41_21*AA[5];
2187 v41_21 = e0[3]-e1[3];
2188 v40_20 = e0[2]-e1[2];
2189 d0[3] = e0[3]+e1[3];
2190 d0[2] = e0[2]+e1[2];
2191 d1[3] = v41_21*AA[0]-v40_20*AA[1];
2192 d1[2] = v40_20*AA[0]+v41_21*AA[1];
2194 AA -= 8;
2196 d0 += 4;
2197 d1 += 4;
2198 e0 += 4;
2199 e1 += 4;
2203 // step 3
2204 ld = ilog(n)-1; // ilog is off-by-one from normal definitions
2206 // optimized step 3:
2208 // the original step3 loop can be nested r inside s or s inside r;
2209 // it's written originally as s inside r, but this is dumb when r
2210 // iterates many times, and s few. So I have two copies of it and
2211 // switch between them halfway.
2213 // this is iteration 0 of step 3
2214 imdct_step3_iter0_loop(n>>4, u, n2-1-n4*0, -(n>>3), A);
2215 imdct_step3_iter0_loop(n>>4, u, n2-1-n4*1, -(n>>3), A);
2217 // this is iteration 1 of step 3
2218 imdct_step3_inner_r_loop(n>>5, u, n2-1-n8*0, -(n>>4), A, 16);
2219 imdct_step3_inner_r_loop(n>>5, u, n2-1-n8*1, -(n>>4), A, 16);
2220 imdct_step3_inner_r_loop(n>>5, u, n2-1-n8*2, -(n>>4), A, 16);
2221 imdct_step3_inner_r_loop(n>>5, u, n2-1-n8*3, -(n>>4), A, 16);
2223 l = 2;
2224 for (; l < (ld-3)>>1; ++l) {
2225 int k0 = n>>(l+2), k0_2 = k0>>1;
2226 int lim = 1<<(l+1);
2227 foreach (int i; 0..lim) imdct_step3_inner_r_loop(n>>(l+4), u, n2-1-k0*i, -k0_2, A, 1<<(l+3));
2230 for (; l < ld-6; ++l) {
2231 int k0 = n>>(l+2), k1 = 1<<(l+3), k0_2 = k0>>1;
2232 int rlim = n>>(l+6);
2233 int lim = 1<<(l+1);
2234 int i_off;
2235 float *A0 = A;
2236 i_off = n2-1;
2237 foreach (immutable _; 0..rlim) {
2238 imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0);
2239 A0 += k1*4;
2240 i_off -= 8;
2244 // iterations with count:
2245 // ld-6,-5,-4 all interleaved together
2246 // the big win comes from getting rid of needless flops
2247 // due to the constants on pass 5 & 4 being all 1 and 0;
2248 // combining them to be simultaneous to improve cache made little difference
2249 imdct_step3_inner_s_loop_ld654(n>>5, u, n2-1, A, n);
2251 // output is u
2253 // step 4, 5, and 6
2254 // cannot be in-place because of step 5
2256 ushort *bitrev = f.bit_reverse.ptr[blocktype];
2257 // weirdly, I'd have thought reading sequentially and writing
2258 // erratically would have been better than vice-versa, but in
2259 // fact that's not what my testing showed. (That is, with
2260 // j = bitreverse(i), do you read i and write j, or read j and write i.)
2261 float *d0 = &v[n4-4];
2262 float *d1 = &v[n2-4];
2263 int k4;
2264 while (d0 >= v) {
2265 k4 = bitrev[0];
2266 d1[3] = u[k4+0];
2267 d1[2] = u[k4+1];
2268 d0[3] = u[k4+2];
2269 d0[2] = u[k4+3];
2271 k4 = bitrev[1];
2272 d1[1] = u[k4+0];
2273 d1[0] = u[k4+1];
2274 d0[1] = u[k4+2];
2275 d0[0] = u[k4+3];
2277 d0 -= 4;
2278 d1 -= 4;
2279 bitrev += 2;
2282 // (paper output is u, now v)
2285 // data must be in buf2
2286 debug(stb_vorbis) assert(v == buf2);
2288 // step 7 (paper output is v, now v)
2289 // this is now in place
2291 float a02, a11, b0, b1, b2, b3;
2292 float* C = f.C.ptr[blocktype];
2293 float* d, e;
2294 d = v;
2295 e = v+n2-4;
2296 while (d < e) {
2297 a02 = d[0]-e[2];
2298 a11 = d[1]+e[3];
2300 b0 = C[1]*a02+C[0]*a11;
2301 b1 = C[1]*a11-C[0]*a02;
2303 b2 = d[0]+e[ 2];
2304 b3 = d[1]-e[ 3];
2306 d[0] = b2+b0;
2307 d[1] = b3+b1;
2308 e[2] = b2-b0;
2309 e[3] = b1-b3;
2311 a02 = d[2]-e[0];
2312 a11 = d[3]+e[1];
2314 b0 = C[3]*a02+C[2]*a11;
2315 b1 = C[3]*a11-C[2]*a02;
2317 b2 = d[2]+e[ 0];
2318 b3 = d[3]-e[ 1];
2320 d[2] = b2+b0;
2321 d[3] = b3+b1;
2322 e[0] = b2-b0;
2323 e[1] = b1-b3;
2325 C += 4;
2326 d += 4;
2327 e -= 4;
2331 // data must be in buf2
2334 // step 8+decode (paper output is X, now buffer)
2335 // this generates pairs of data a la 8 and pushes them directly through
2336 // the decode kernel (pushing rather than pulling) to avoid having
2337 // to make another pass later
2339 // this cannot POSSIBLY be in place, so we refer to the buffers directly
2341 float p0, p1, p2, p3;
2342 float* d0, d1, d2, d3;
2343 float* B = f.B.ptr[blocktype]+n2-8;
2344 float* e = buf2+n2-8;
2345 d0 = &buffer[0];
2346 d1 = &buffer[n2-4];
2347 d2 = &buffer[n2];
2348 d3 = &buffer[n-4];
2349 while (e >= v) {
2350 p3 = e[6]*B[7]-e[7]*B[6];
2351 p2 = -e[6]*B[6]-e[7]*B[7];
2353 d0[0] = p3;
2354 d1[3] = -p3;
2355 d2[0] = p2;
2356 d3[3] = p2;
2358 p1 = e[4]*B[5]-e[5]*B[4];
2359 p0 = -e[4]*B[4]-e[5]*B[5];
2361 d0[1] = p1;
2362 d1[2] = - p1;
2363 d2[1] = p0;
2364 d3[2] = p0;
2366 p3 = e[2]*B[3]-e[3]*B[2];
2367 p2 = -e[2]*B[2]-e[3]*B[3];
2369 d0[2] = p3;
2370 d1[1] = - p3;
2371 d2[2] = p2;
2372 d3[1] = p2;
2374 p1 = e[0]*B[1]-e[1]*B[0];
2375 p0 = -e[0]*B[0]-e[1]*B[1];
2377 d0[3] = p1;
2378 d1[0] = - p1;
2379 d2[3] = p0;
2380 d3[0] = p0;
2382 B -= 8;
2383 e -= 8;
2384 d0 += 4;
2385 d2 += 4;
2386 d1 -= 4;
2387 d3 -= 4;
2391 temp_free(f, buf2);
2392 temp_alloc_restore(f, save_point);
2395 private float *get_window (VorbisDecoder f, int len) {
2396 len <<= 1;
2397 if (len == f.blocksize_0) return f.window.ptr[0];
2398 if (len == f.blocksize_1) return f.window.ptr[1];
2399 assert(0);
2402 version(STB_VORBIS_NO_DEFER_FLOOR) {
2403 alias YTYPE = int;
2404 } else {
2405 alias YTYPE = short;
2408 private int do_floor (VorbisDecoder f, Mapping* map, int i, int n, float* target, YTYPE* finalY, ubyte* step2_flag) {
2409 int n2 = n>>1;
2410 int s = map.chan[i].mux, floor;
2411 floor = map.submap_floor.ptr[s];
2412 if (f.floor_types.ptr[floor] == 0) {
2413 return error(f, STBVorbisError.invalid_stream);
2414 } else {
2415 Floor1* g = &f.floor_config[floor].floor1;
2416 int lx = 0, ly = finalY[0]*g.floor1_multiplier;
2417 foreach (immutable q; 1..g.values) {
2418 int j = g.sorted_order.ptr[q];
2419 version(STB_VORBIS_NO_DEFER_FLOOR) {
2420 auto cond = step2_flag[j];
2421 } else {
2422 auto cond = (finalY[j] >= 0);
2424 if (cond) {
2425 int hy = finalY[j]*g.floor1_multiplier;
2426 int hx = g.Xlist.ptr[j];
2427 if (lx != hx) { mixin(draw_line!("target", "lx", "ly", "hx", "hy", "n2")); }
2428 lx = hx; ly = hy;
2431 if (lx < n2) {
2432 // optimization of: draw_line(target, lx, ly, n, ly, n2);
2433 foreach (immutable j; lx..n2) { mixin(LINE_OP!("target[j]", "inverse_db_table[ly]")); }
2436 return true;
2439 // The meaning of "left" and "right"
2441 // For a given frame:
2442 // we compute samples from 0..n
2443 // window_center is n/2
2444 // we'll window and mix the samples from left_start to left_end with data from the previous frame
2445 // all of the samples from left_end to right_start can be output without mixing; however,
2446 // this interval is 0-length except when transitioning between short and long frames
2447 // all of the samples from right_start to right_end need to be mixed with the next frame,
2448 // which we don't have, so those get saved in a buffer
2449 // frame N's right_end-right_start, the number of samples to mix with the next frame,
2450 // has to be the same as frame N+1's left_end-left_start (which they are by
2451 // construction)
2453 private int vorbis_decode_initial (VorbisDecoder f, int* p_left_start, int* p_left_end, int* p_right_start, int* p_right_end, int* mode) {
2454 Mode *m;
2455 int i, n, prev, next, window_center;
2456 f.channel_buffer_start = f.channel_buffer_end = 0;
2458 retry:
2459 if (f.eof) return false;
2460 if (!maybe_start_packet(f)) return false;
2461 // check packet type
2462 if (get_bits!1(f) != 0) {
2463 /+if (f.push_mode) return error(f, STBVorbisError.bad_packet_type);+/
2464 while (EOP != get8_packet(f)) {}
2465 goto retry;
2468 //debug(stb_vorbis) if (f.alloc.alloc_buffer) assert(f.alloc.alloc_buffer_length_in_bytes == f.temp_offset);
2470 i = get_bits_main(f, ilog(f.mode_count-1));
2471 if (i == EOP) return false;
2472 if (i >= f.mode_count) return false;
2473 *mode = i;
2474 m = f.mode_config.ptr+i;
2475 if (m.blockflag) {
2476 n = f.blocksize_1;
2477 prev = get_bits!1(f);
2478 next = get_bits!1(f);
2479 } else {
2480 prev = next = 0;
2481 n = f.blocksize_0;
2484 // WINDOWING
2485 window_center = n>>1;
2486 if (m.blockflag && !prev) {
2487 *p_left_start = (n-f.blocksize_0)>>2;
2488 *p_left_end = (n+f.blocksize_0)>>2;
2489 } else {
2490 *p_left_start = 0;
2491 *p_left_end = window_center;
2493 if (m.blockflag && !next) {
2494 *p_right_start = (n*3-f.blocksize_0)>>2;
2495 *p_right_end = (n*3+f.blocksize_0)>>2;
2496 } else {
2497 *p_right_start = window_center;
2498 *p_right_end = n;
2500 return true;
2503 private int vorbis_decode_packet_rest (VorbisDecoder f, int* len, Mode* m, int left_start, int left_end, int right_start, int right_end, int* p_left) {
2504 import core.stdc.string : memcpy, memset;
2506 Mapping* map;
2507 int n, n2;
2508 int[256] zero_channel;
2509 int[256] really_zero_channel;
2511 // WINDOWING
2512 n = f.blocksize.ptr[m.blockflag];
2513 map = &f.mapping[m.mapping];
2515 // FLOORS
2516 n2 = n>>1;
2518 //stb_prof(1);
2519 foreach (immutable i; 0..f.vrchannels) {
2520 int s = map.chan[i].mux, floor;
2521 zero_channel[i] = false;
2522 floor = map.submap_floor.ptr[s];
2523 if (f.floor_types.ptr[floor] == 0) {
2524 return error(f, STBVorbisError.invalid_stream);
2525 } else {
2526 Floor1* g = &f.floor_config[floor].floor1;
2527 if (get_bits!1(f)) {
2528 short* finalY;
2529 ubyte[256] step2_flag = void;
2530 immutable int[4] range_list = [ 256, 128, 86, 64 ];
2531 int range = range_list[g.floor1_multiplier-1];
2532 int offset = 2;
2533 finalY = f.finalY.ptr[i];
2534 finalY[0] = cast(short)get_bits_main(f, ilog(range)-1); //k8
2535 finalY[1] = cast(short)get_bits_main(f, ilog(range)-1); //k8
2536 foreach (immutable j; 0..g.partitions) {
2537 int pclass = g.partition_class_list.ptr[j];
2538 int cdim = g.class_dimensions.ptr[pclass];
2539 int cbits = g.class_subclasses.ptr[pclass];
2540 int csub = (1<<cbits)-1;
2541 int cval = 0;
2542 if (cbits) {
2543 Codebook *cc = f.codebooks+g.class_masterbooks.ptr[pclass];
2544 mixin(DECODE!("cval", "cc"));
2546 foreach (immutable k; 0..cdim) {
2547 int book = g.subclass_books.ptr[pclass].ptr[cval&csub];
2548 cval = cval>>cbits;
2549 if (book >= 0) {
2550 int temp;
2551 Codebook *cc = f.codebooks+book;
2552 mixin(DECODE!("temp", "cc"));
2553 finalY[offset++] = cast(short)temp; //k8
2554 } else {
2555 finalY[offset++] = 0;
2559 if (f.valid_bits == INVALID_BITS) goto error; // behavior according to spec
2560 step2_flag[0] = step2_flag[1] = 1;
2561 foreach (immutable j; 2..g.values) {
2562 int low = g.neighbors.ptr[j].ptr[0];
2563 int high = g.neighbors.ptr[j].ptr[1];
2564 //neighbors(g.Xlist, j, &low, &high);
2565 int pred = void;
2566 mixin(predict_point!("pred", "g.Xlist.ptr[j]", "g.Xlist.ptr[low]", "g.Xlist.ptr[high]", "finalY[low]", "finalY[high]"));
2567 int val = finalY[j];
2568 int highroom = range-pred;
2569 int lowroom = pred;
2570 auto room = (highroom < lowroom ? highroom : lowroom)*2;
2571 if (val) {
2572 step2_flag[low] = step2_flag[high] = 1;
2573 step2_flag[j] = 1;
2574 if (val >= room) {
2575 finalY[j] = cast(short)(highroom > lowroom ? val-lowroom+pred : pred-val+highroom-1); //k8
2576 } else {
2577 finalY[j] = cast(short)(val&1 ? pred-((val+1)>>1) : pred+(val>>1)); //k8
2579 } else {
2580 step2_flag[j] = 0;
2581 finalY[j] = cast(short)pred; //k8
2585 version(STB_VORBIS_NO_DEFER_FLOOR) {
2586 do_floor(f, map, i, n, f.floor_buffers.ptr[i], finalY, step2_flag);
2587 } else {
2588 // defer final floor computation until _after_ residue
2589 foreach (immutable j; 0..g.values) if (!step2_flag[j]) finalY[j] = -1;
2591 } else {
2592 error:
2593 zero_channel[i] = true;
2595 // So we just defer everything else to later
2596 // at this point we've decoded the floor into buffer
2599 //stb_prof(0);
2600 // at this point we've decoded all floors
2602 //debug(stb_vorbis) if (f.alloc.alloc_buffer) assert(f.alloc.alloc_buffer_length_in_bytes == f.temp_offset);
2604 // re-enable coupled channels if necessary
2605 memcpy(really_zero_channel.ptr, zero_channel.ptr, (really_zero_channel[0]).sizeof*f.vrchannels);
2606 foreach (immutable i; 0..map.coupling_steps) {
2607 if (!zero_channel[map.chan[i].magnitude] || !zero_channel[map.chan[i].angle]) {
2608 zero_channel[map.chan[i].magnitude] = zero_channel[map.chan[i].angle] = false;
2612 // RESIDUE DECODE
2613 foreach (immutable i; 0..map.submaps) {
2614 float*[STB_VORBIS_MAX_CHANNELS] residue_buffers;
2615 ubyte[256] do_not_decode = void;
2616 int ch = 0;
2617 foreach (immutable j; 0..f.vrchannels) {
2618 if (map.chan[j].mux == i) {
2619 if (zero_channel[j]) {
2620 do_not_decode[ch] = true;
2621 residue_buffers.ptr[ch] = null;
2622 } else {
2623 do_not_decode[ch] = false;
2624 residue_buffers.ptr[ch] = f.channel_buffers.ptr[j];
2626 ++ch;
2629 int r = map.submap_residue.ptr[i];
2630 decode_residue(f, residue_buffers, ch, n2, r, do_not_decode.ptr);
2633 //debug(stb_vorbis) if (f.alloc.alloc_buffer) assert(f.alloc.alloc_buffer_length_in_bytes == f.temp_offset);
2635 // INVERSE COUPLING
2636 //stb_prof(14);
2637 foreach_reverse (immutable i; 0..map.coupling_steps) {
2638 int n2n = n>>1;
2639 float* mm = f.channel_buffers.ptr[map.chan[i].magnitude];
2640 float* a = f.channel_buffers.ptr[map.chan[i].angle];
2641 foreach (immutable j; 0..n2n) {
2642 float a2, m2;
2643 if (mm[j] > 0) {
2644 if (a[j] > 0) { m2 = mm[j]; a2 = mm[j]-a[j]; } else { a2 = mm[j]; m2 = mm[j]+a[j]; }
2645 } else {
2646 if (a[j] > 0) { m2 = mm[j]; a2 = mm[j]+a[j]; } else { a2 = mm[j]; m2 = mm[j]-a[j]; }
2648 mm[j] = m2;
2649 a[j] = a2;
2653 // finish decoding the floors
2654 version(STB_VORBIS_NO_DEFER_FLOOR) {
2655 foreach (immutable i; 0..f.vrchannels) {
2656 if (really_zero_channel[i]) {
2657 memset(f.channel_buffers.ptr[i], 0, (*f.channel_buffers.ptr[i]).sizeof*n2);
2658 } else {
2659 foreach (immutable j; 0..n2) f.channel_buffers.ptr[i].ptr[j] *= f.floor_buffers.ptr[i].ptr[j];
2662 } else {
2663 //stb_prof(15);
2664 foreach (immutable i; 0..f.vrchannels) {
2665 if (really_zero_channel[i]) {
2666 memset(f.channel_buffers.ptr[i], 0, (*f.channel_buffers.ptr[i]).sizeof*n2);
2667 } else {
2668 do_floor(f, map, i, n, f.channel_buffers.ptr[i], f.finalY.ptr[i], null);
2673 // INVERSE MDCT
2674 //stb_prof(16);
2675 foreach (immutable i; 0..f.vrchannels) inverse_mdct(f.channel_buffers.ptr[i], n, f, m.blockflag);
2676 //stb_prof(0);
2678 // this shouldn't be necessary, unless we exited on an error
2679 // and want to flush to get to the next packet
2680 flush_packet(f);
2682 if (f.first_decode) {
2683 // assume we start so first non-discarded sample is sample 0
2684 // this isn't to spec, but spec would require us to read ahead
2685 // and decode the size of all current frames--could be done,
2686 // but presumably it's not a commonly used feature
2687 f.current_loc = -n2; // start of first frame is positioned for discard
2688 // we might have to discard samples "from" the next frame too,
2689 // if we're lapping a large block then a small at the start?
2690 f.discard_samples_deferred = n-right_end;
2691 f.current_loc_valid = true;
2692 f.first_decode = false;
2693 } else if (f.discard_samples_deferred) {
2694 if (f.discard_samples_deferred >= right_start-left_start) {
2695 f.discard_samples_deferred -= (right_start-left_start);
2696 left_start = right_start;
2697 *p_left = left_start;
2698 } else {
2699 left_start += f.discard_samples_deferred;
2700 *p_left = left_start;
2701 f.discard_samples_deferred = 0;
2703 } else if (f.previous_length == 0 && f.current_loc_valid) {
2704 // we're recovering from a seek... that means we're going to discard
2705 // the samples from this packet even though we know our position from
2706 // the last page header, so we need to update the position based on
2707 // the discarded samples here
2708 // but wait, the code below is going to add this in itself even
2709 // on a discard, so we don't need to do it here...
2712 // check if we have ogg information about the sample # for this packet
2713 if (f.last_seg_which == f.end_seg_with_known_loc) {
2714 // if we have a valid current loc, and this is final:
2715 if (f.current_loc_valid && (f.page_flag&PAGEFLAG_last_page)) {
2716 uint current_end = f.known_loc_for_packet-(n-right_end);
2717 // then let's infer the size of the (probably) short final frame
2718 if (current_end < f.current_loc+right_end) {
2719 if (current_end < f.current_loc+(right_end-left_start)) {
2720 // negative truncation, that's impossible!
2721 *len = 0;
2722 } else {
2723 *len = current_end-f.current_loc;
2725 *len += left_start;
2726 if (*len > right_end) *len = right_end; // this should never happen
2727 f.current_loc += *len;
2728 return true;
2731 // otherwise, just set our sample loc
2732 // guess that the ogg granule pos refers to the _middle_ of the
2733 // last frame?
2734 // set f.current_loc to the position of left_start
2735 f.current_loc = f.known_loc_for_packet-(n2-left_start);
2736 f.current_loc_valid = true;
2738 if (f.current_loc_valid) f.current_loc += (right_start-left_start);
2740 //debug(stb_vorbis) if (f.alloc.alloc_buffer) assert(f.alloc.alloc_buffer_length_in_bytes == f.temp_offset);
2742 *len = right_end; // ignore samples after the window goes to 0
2743 return true;
2746 private int vorbis_decode_packet (VorbisDecoder f, int* len, int* p_left, int* p_right) {
2747 int mode, left_end, right_end;
2748 if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0;
2749 return vorbis_decode_packet_rest(f, len, f.mode_config.ptr+mode, *p_left, left_end, *p_right, right_end, p_left);
2752 private int vorbis_finish_frame (VorbisDecoder f, int len, int left, int right) {
2753 // we use right&left (the start of the right- and left-window sin()-regions)
2754 // to determine how much to return, rather than inferring from the rules
2755 // (same result, clearer code); 'left' indicates where our sin() window
2756 // starts, therefore where the previous window's right edge starts, and
2757 // therefore where to start mixing from the previous buffer. 'right'
2758 // indicates where our sin() ending-window starts, therefore that's where
2759 // we start saving, and where our returned-data ends.
2761 // mixin from previous window
2762 if (f.previous_length) {
2763 int n = f.previous_length;
2764 float *w = get_window(f, n);
2765 foreach (immutable i; 0..f.vrchannels) {
2766 foreach (immutable j; 0..n) {
2767 (f.channel_buffers.ptr[i])[left+j] =
2768 (f.channel_buffers.ptr[i])[left+j]*w[ j]+
2769 (f.previous_window.ptr[i])[ j]*w[n-1-j];
2774 auto prev = f.previous_length;
2776 // last half of this data becomes previous window
2777 f.previous_length = len-right;
2779 // @OPTIMIZE: could avoid this copy by double-buffering the
2780 // output (flipping previous_window with channel_buffers), but
2781 // then previous_window would have to be 2x as large, and
2782 // channel_buffers couldn't be temp mem (although they're NOT
2783 // currently temp mem, they could be (unless we want to level
2784 // performance by spreading out the computation))
2785 foreach (immutable i; 0..f.vrchannels) {
2786 for (uint j = 0; right+j < len; ++j) (f.previous_window.ptr[i])[j] = (f.channel_buffers.ptr[i])[right+j];
2789 if (!prev) {
2790 // there was no previous packet, so this data isn't valid...
2791 // this isn't entirely true, only the would-have-overlapped data
2792 // isn't valid, but this seems to be what the spec requires
2793 return 0;
2796 // truncate a short frame
2797 if (len < right) right = len;
2799 f.samples_output += right-left;
2801 return right-left;
2804 private bool vorbis_pump_first_frame (VorbisDecoder f) {
2805 int len, right, left;
2806 if (vorbis_decode_packet(f, &len, &left, &right)) {
2807 vorbis_finish_frame(f, len, left, right);
2808 return true;
2810 return false;
2813 /+ k8: i don't need that, so it's dead
2814 private int is_whole_packet_present (VorbisDecoder f, int end_page) {
2815 import core.stdc.string : memcmp;
2817 // make sure that we have the packet available before continuing...
2818 // this requires a full ogg parse, but we know we can fetch from f.stream
2820 // instead of coding this out explicitly, we could save the current read state,
2821 // read the next packet with get8() until end-of-packet, check f.eof, then
2822 // reset the state? but that would be slower, esp. since we'd have over 256 bytes
2823 // of state to restore (primarily the page segment table)
2825 int s = f.next_seg, first = true;
2826 ubyte *p = f.stream;
2828 if (s != -1) { // if we're not starting the packet with a 'continue on next page' flag
2829 for (; s < f.segment_count; ++s) {
2830 p += f.segments[s];
2831 if (f.segments[s] < 255) break; // stop at first short segment
2833 // either this continues, or it ends it...
2834 if (end_page && s < f.segment_count-1) return error(f, STBVorbisError.invalid_stream);
2835 if (s == f.segment_count) s = -1; // set 'crosses page' flag
2836 if (p > f.stream_end) return error(f, STBVorbisError.need_more_data);
2837 first = false;
2839 while (s == -1) {
2840 ubyte* q = void;
2841 int n = void;
2842 // check that we have the page header ready
2843 if (p+26 >= f.stream_end) return error(f, STBVorbisError.need_more_data);
2844 // validate the page
2845 if (memcmp(p, ogg_page_header.ptr, 4)) return error(f, STBVorbisError.invalid_stream);
2846 if (p[4] != 0) return error(f, STBVorbisError.invalid_stream);
2847 if (first) { // the first segment must NOT have 'continued_packet', later ones MUST
2848 if (f.previous_length && (p[5]&PAGEFLAG_continued_packet)) return error(f, STBVorbisError.invalid_stream);
2849 // if no previous length, we're resynching, so we can come in on a continued-packet,
2850 // which we'll just drop
2851 } else {
2852 if (!(p[5]&PAGEFLAG_continued_packet)) return error(f, STBVorbisError.invalid_stream);
2854 n = p[26]; // segment counts
2855 q = p+27; // q points to segment table
2856 p = q+n; // advance past header
2857 // make sure we've read the segment table
2858 if (p > f.stream_end) return error(f, STBVorbisError.need_more_data);
2859 for (s = 0; s < n; ++s) {
2860 p += q[s];
2861 if (q[s] < 255) break;
2863 if (end_page && s < n-1) return error(f, STBVorbisError.invalid_stream);
2864 if (s == n) s = -1; // set 'crosses page' flag
2865 if (p > f.stream_end) return error(f, STBVorbisError.need_more_data);
2866 first = false;
2868 return true;
2872 private int start_decoder (VorbisDecoder f) {
2873 import core.stdc.string : memcpy, memset;
2875 ubyte[6] header;
2876 ubyte x, y;
2877 int len, max_submaps = 0;
2878 int longest_floorlist = 0;
2880 // first page, first packet
2882 if (!start_page(f)) return false;
2883 // validate page flag
2884 if (!(f.page_flag&PAGEFLAG_first_page)) return error(f, STBVorbisError.invalid_first_page);
2885 if (f.page_flag&PAGEFLAG_last_page) return error(f, STBVorbisError.invalid_first_page);
2886 if (f.page_flag&PAGEFLAG_continued_packet) return error(f, STBVorbisError.invalid_first_page);
2887 // check for expected packet length
2888 if (f.segment_count != 1) return error(f, STBVorbisError.invalid_first_page);
2889 if (f.segments[0] != 30) return error(f, STBVorbisError.invalid_first_page);
2890 // read packet
2891 // check packet header
2892 if (get8(f) != VorbisPacket.id) return error(f, STBVorbisError.invalid_first_page);
2893 if (!getn(f, header.ptr, 6)) return error(f, STBVorbisError.unexpected_eof);
2894 if (!vorbis_validate(header.ptr)) return error(f, STBVorbisError.invalid_first_page);
2895 // vorbis_version
2896 if (get32(f) != 0) return error(f, STBVorbisError.invalid_first_page);
2897 f.vrchannels = get8(f); if (!f.vrchannels) return error(f, STBVorbisError.invalid_first_page);
2898 if (f.vrchannels > STB_VORBIS_MAX_CHANNELS) return error(f, STBVorbisError.too_many_channels);
2899 f.sample_rate = get32(f); if (!f.sample_rate) return error(f, STBVorbisError.invalid_first_page);
2900 get32(f); // bitrate_maximum
2901 get32(f); // bitrate_nominal
2902 get32(f); // bitrate_minimum
2903 x = get8(f);
2905 int log0 = x&15;
2906 int log1 = x>>4;
2907 f.blocksize_0 = 1<<log0;
2908 f.blocksize_1 = 1<<log1;
2909 if (log0 < 6 || log0 > 13) return error(f, STBVorbisError.invalid_setup);
2910 if (log1 < 6 || log1 > 13) return error(f, STBVorbisError.invalid_setup);
2911 if (log0 > log1) return error(f, STBVorbisError.invalid_setup);
2914 // framing_flag
2915 x = get8(f);
2916 if (!(x&1)) return error(f, STBVorbisError.invalid_first_page);
2918 // second packet! (comments)
2919 if (!start_page(f)) return false;
2921 // read comments
2922 if (!start_packet(f)) return false;
2924 if (f.read_comments) {
2925 /+if (f.push_mode) {
2926 if (!is_whole_packet_present(f, true)) {
2927 // convert error in ogg header to write type
2928 if (f.error == STBVorbisError.invalid_stream) f.error = STBVorbisError.invalid_setup;
2929 return false;
2932 if (get8_packet(f) != VorbisPacket.comment) return error(f, STBVorbisError.invalid_setup);
2933 foreach (immutable i; 0..6) header[i] = cast(ubyte)get8_packet(f); //k8
2934 if (!vorbis_validate(header.ptr)) return error(f, STBVorbisError.invalid_setup);
2936 // skip vendor id
2937 uint vidsize = get32_packet(f);
2938 //{ import core.stdc.stdio; printf("vendor size: %u\n", vidsize); }
2939 if (vidsize == EOP) return error(f, STBVorbisError.invalid_setup);
2940 while (vidsize--) get8_packet(f);
2942 // read comments section
2943 uint cmtcount = get32_packet(f);
2944 if (cmtcount == EOP) return error(f, STBVorbisError.invalid_setup);
2945 if (cmtcount > 0) {
2946 uint cmtsize = 32768; // this should be enough for everyone
2947 f.comment_data = setup_malloc!ubyte(f, cmtsize);
2948 if (f.comment_data is null) return error(f, STBVorbisError.outofmem);
2949 auto cmtpos = 0;
2950 auto d = f.comment_data;
2951 while (cmtcount--) {
2952 uint linelen = get32_packet(f);
2953 //{ import core.stdc.stdio; printf("linelen: %u; lines left: %u\n", linelen, cmtcount); }
2954 if (linelen == EOP || linelen > ushort.max-2) break;
2955 if (linelen == 0) { continue; }
2956 if (cmtpos+2+linelen > cmtsize) break;
2957 cmtpos += linelen+2;
2958 *d++ = (linelen+2)&0xff;
2959 *d++ = ((linelen+2)>>8)&0xff;
2960 while (linelen--) {
2961 auto b = get8_packet(f);
2962 if (b == EOP) return error(f, STBVorbisError.outofmem);
2963 *d++ = cast(ubyte)b;
2965 //{ import core.stdc.stdio; printf("%u bytes of comments read\n", cmtpos); }
2966 f.comment_size = cmtpos;
2969 flush_packet(f);
2970 f.comment_rewind();
2971 } else {
2972 // skip comments
2973 do {
2974 len = next_segment(f);
2975 skip(f, len);
2976 f.bytes_in_seg = 0;
2977 } while (len);
2980 // third packet!
2981 if (!start_packet(f)) return false;
2983 /+if (f.push_mode) {
2984 if (!is_whole_packet_present(f, true)) {
2985 // convert error in ogg header to write type
2986 if (f.error == STBVorbisError.invalid_stream) f.error = STBVorbisError.invalid_setup;
2987 return false;
2991 if (get8_packet(f) != VorbisPacket.setup) return error(f, STBVorbisError.invalid_setup);
2992 foreach (immutable i; 0..6) header[i] = cast(ubyte)get8_packet(f); //k8
2993 if (!vorbis_validate(header.ptr)) return error(f, STBVorbisError.invalid_setup);
2995 // codebooks
2996 f.codebook_count = get_bits!8(f)+1;
2997 f.codebooks = setup_malloc!Codebook(f, f.codebook_count);
2998 static assert((*f.codebooks).sizeof == Codebook.sizeof);
2999 if (f.codebooks is null) return error(f, STBVorbisError.outofmem);
3000 memset(f.codebooks, 0, (*f.codebooks).sizeof*f.codebook_count);
3001 foreach (immutable i; 0..f.codebook_count) {
3002 uint* values;
3003 int ordered, sorted_count;
3004 int total = 0;
3005 ubyte* lengths;
3006 Codebook* c = f.codebooks+i;
3007 x = get_bits!8(f); if (x != 0x42) return error(f, STBVorbisError.invalid_setup);
3008 x = get_bits!8(f); if (x != 0x43) return error(f, STBVorbisError.invalid_setup);
3009 x = get_bits!8(f); if (x != 0x56) return error(f, STBVorbisError.invalid_setup);
3010 x = get_bits!8(f);
3011 c.dimensions = (get_bits!8(f)<<8)+x;
3012 x = get_bits!8(f);
3013 y = get_bits!8(f);
3014 c.entries = (get_bits!8(f)<<16)+(y<<8)+x;
3015 ordered = get_bits!1(f);
3016 c.sparse = (ordered ? 0 : get_bits!1(f));
3018 if (c.dimensions == 0 && c.entries != 0) return error(f, STBVorbisError.invalid_setup);
3020 if (c.sparse) {
3021 lengths = cast(ubyte*)setup_temp_malloc(f, c.entries);
3022 } else {
3023 lengths = c.codeword_lengths = setup_malloc!ubyte(f, c.entries);
3026 if (lengths is null) return error(f, STBVorbisError.outofmem);
3028 if (ordered) {
3029 int current_entry = 0;
3030 int current_length = get_bits_add_no!5(f, 1);
3031 while (current_entry < c.entries) {
3032 int limit = c.entries-current_entry;
3033 int n = get_bits_main(f, ilog(limit));
3034 if (current_entry+n > cast(int)c.entries) return error(f, STBVorbisError.invalid_setup);
3035 memset(lengths+current_entry, current_length, n);
3036 current_entry += n;
3037 ++current_length;
3039 } else {
3040 foreach (immutable j; 0..c.entries) {
3041 int present = (c.sparse ? get_bits!1(f) : 1);
3042 if (present) {
3043 lengths[j] = get_bits_add_no!5(f, 1);
3044 ++total;
3045 if (lengths[j] == 32) return error(f, STBVorbisError.invalid_setup);
3046 } else {
3047 lengths[j] = NO_CODE;
3052 if (c.sparse && total >= c.entries>>2) {
3053 // convert sparse items to non-sparse!
3054 if (c.entries > cast(int)f.setup_temp_memory_required) f.setup_temp_memory_required = c.entries;
3055 c.codeword_lengths = setup_malloc!ubyte(f, c.entries);
3056 if (c.codeword_lengths is null) return error(f, STBVorbisError.outofmem);
3057 memcpy(c.codeword_lengths, lengths, c.entries);
3058 setup_temp_free(f, lengths, c.entries); // note this is only safe if there have been no intervening temp mallocs!
3059 lengths = c.codeword_lengths;
3060 c.sparse = 0;
3063 // compute the size of the sorted tables
3064 if (c.sparse) {
3065 sorted_count = total;
3066 } else {
3067 sorted_count = 0;
3068 version(STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH) {} else {
3069 foreach (immutable j; 0..c.entries) if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && lengths[j] != NO_CODE) ++sorted_count;
3073 c.sorted_entries = sorted_count;
3074 values = null;
3076 if (!c.sparse) {
3077 c.codewords = setup_malloc!uint(f, c.entries);
3078 if (!c.codewords) return error(f, STBVorbisError.outofmem);
3079 } else {
3080 if (c.sorted_entries) {
3081 c.codeword_lengths = setup_malloc!ubyte(f, c.sorted_entries);
3082 if (!c.codeword_lengths) return error(f, STBVorbisError.outofmem);
3083 c.codewords = cast(uint*)setup_temp_malloc(f, cast(int)(*c.codewords).sizeof*c.sorted_entries);
3084 if (!c.codewords) return error(f, STBVorbisError.outofmem);
3085 values = cast(uint*)setup_temp_malloc(f, cast(int)(*values).sizeof*c.sorted_entries);
3086 if (!values) return error(f, STBVorbisError.outofmem);
3088 uint size = c.entries+cast(int)((*c.codewords).sizeof+(*values).sizeof)*c.sorted_entries;
3089 if (size > f.setup_temp_memory_required) f.setup_temp_memory_required = size;
3092 if (!compute_codewords(c, lengths, c.entries, values)) {
3093 if (c.sparse) setup_temp_free(f, values, 0);
3094 return error(f, STBVorbisError.invalid_setup);
3097 if (c.sorted_entries) {
3098 // allocate an extra slot for sentinels
3099 c.sorted_codewords = setup_malloc!uint(f, c.sorted_entries+1);
3100 if (c.sorted_codewords is null) return error(f, STBVorbisError.outofmem);
3101 // allocate an extra slot at the front so that c.sorted_values[-1] is defined
3102 // so that we can catch that case without an extra if
3103 c.sorted_values = setup_malloc!int(f, c.sorted_entries+1);
3104 if (c.sorted_values is null) return error(f, STBVorbisError.outofmem);
3105 ++c.sorted_values;
3106 c.sorted_values[-1] = -1;
3107 compute_sorted_huffman(c, lengths, values);
3110 if (c.sparse) {
3111 setup_temp_free(f, values, cast(int)(*values).sizeof*c.sorted_entries);
3112 setup_temp_free(f, c.codewords, cast(int)(*c.codewords).sizeof*c.sorted_entries);
3113 setup_temp_free(f, lengths, c.entries);
3114 c.codewords = null;
3117 compute_accelerated_huffman(c);
3119 c.lookup_type = get_bits!4(f);
3120 if (c.lookup_type > 2) return error(f, STBVorbisError.invalid_setup);
3121 if (c.lookup_type > 0) {
3122 ushort* mults;
3123 c.minimum_value = float32_unpack(get_bits!32(f));
3124 c.delta_value = float32_unpack(get_bits!32(f));
3125 c.value_bits = get_bits_add_no!4(f, 1);
3126 c.sequence_p = get_bits!1(f);
3127 if (c.lookup_type == 1) {
3128 c.lookup_values = lookup1_values(c.entries, c.dimensions);
3129 } else {
3130 c.lookup_values = c.entries*c.dimensions;
3132 if (c.lookup_values == 0) return error(f, STBVorbisError.invalid_setup);
3133 mults = cast(ushort*)setup_temp_malloc(f, cast(int)(mults[0]).sizeof*c.lookup_values);
3134 if (mults is null) return error(f, STBVorbisError.outofmem);
3135 foreach (immutable j; 0..cast(int)c.lookup_values) {
3136 int q = get_bits_main(f, c.value_bits);
3137 if (q == EOP) { setup_temp_free(f, mults, cast(int)(mults[0]).sizeof*c.lookup_values); return error(f, STBVorbisError.invalid_setup); }
3138 mults[j] = cast(ushort)q; //k8
3141 version(STB_VORBIS_DIVIDES_IN_CODEBOOK) {} else {
3142 if (c.lookup_type == 1) {
3143 int sparse = c.sparse; //len
3144 float last = 0;
3145 // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop
3146 if (sparse) {
3147 if (c.sorted_entries == 0) goto skip;
3148 c.multiplicands = setup_malloc!codetype(f, c.sorted_entries*c.dimensions);
3149 } else {
3150 c.multiplicands = setup_malloc!codetype(f, c.entries*c.dimensions);
3152 if (c.multiplicands is null) { setup_temp_free(f, mults, cast(int)(mults[0]).sizeof*c.lookup_values); return error(f, STBVorbisError.outofmem); }
3153 foreach (immutable j; 0..(sparse ? c.sorted_entries : c.entries)) {
3154 uint z = (sparse ? c.sorted_values[j] : j);
3155 uint div = 1;
3156 foreach (immutable k; 0..c.dimensions) {
3157 int off = (z/div)%c.lookup_values;
3158 float val = mults[off];
3159 val = val*c.delta_value+c.minimum_value+last;
3160 c.multiplicands[j*c.dimensions+k] = val;
3161 if (c.sequence_p) last = val;
3162 if (k+1 < c.dimensions) {
3163 if (div > uint.max/cast(uint)c.lookup_values) {
3164 setup_temp_free(f, mults, cast(uint)(mults[0]).sizeof*c.lookup_values);
3165 return error(f, STBVorbisError.invalid_setup);
3167 div *= c.lookup_values;
3171 c.lookup_type = 2;
3172 goto skip;
3174 //else
3177 float last = 0;
3178 c.multiplicands = setup_malloc!codetype(f, c.lookup_values);
3179 if (c.multiplicands is null) { setup_temp_free(f, mults, cast(uint)(mults[0]).sizeof*c.lookup_values); return error(f, STBVorbisError.outofmem); }
3180 foreach (immutable j; 0..cast(int)c.lookup_values) {
3181 float val = mults[j]*c.delta_value+c.minimum_value+last;
3182 c.multiplicands[j] = val;
3183 if (c.sequence_p) last = val;
3186 //version(STB_VORBIS_DIVIDES_IN_CODEBOOK)
3187 skip: // this is versioned out in C
3188 setup_temp_free(f, mults, cast(uint)(mults[0]).sizeof*c.lookup_values);
3192 // time domain transfers (notused)
3193 x = get_bits_add_no!6(f, 1);
3194 foreach (immutable i; 0..x) {
3195 auto z = get_bits!16(f);
3196 if (z != 0) return error(f, STBVorbisError.invalid_setup);
3199 // Floors
3200 f.floor_count = get_bits_add_no!6(f, 1);
3201 f.floor_config = setup_malloc!Floor(f, f.floor_count);
3202 if (f.floor_config is null) return error(f, STBVorbisError.outofmem);
3203 foreach (immutable i; 0..f.floor_count) {
3204 f.floor_types[i] = get_bits!16(f);
3205 if (f.floor_types[i] > 1) return error(f, STBVorbisError.invalid_setup);
3206 if (f.floor_types[i] == 0) {
3207 Floor0* g = &f.floor_config[i].floor0;
3208 g.order = get_bits!8(f);
3209 g.rate = get_bits!16(f);
3210 g.bark_map_size = get_bits!16(f);
3211 g.amplitude_bits = get_bits!6(f);
3212 g.amplitude_offset = get_bits!8(f);
3213 g.number_of_books = get_bits_add_no!4(f, 1);
3214 foreach (immutable j; 0..g.number_of_books) g.book_list[j] = get_bits!8(f);
3215 return error(f, STBVorbisError.feature_not_supported);
3216 } else {
3217 Point[31*8+2] p;
3218 Floor1 *g = &f.floor_config[i].floor1;
3219 int max_class = -1;
3220 g.partitions = get_bits!5(f);
3221 foreach (immutable j; 0..g.partitions) {
3222 g.partition_class_list[j] = get_bits!4(f);
3223 if (g.partition_class_list[j] > max_class) max_class = g.partition_class_list[j];
3225 foreach (immutable j; 0..max_class+1) {
3226 g.class_dimensions[j] = get_bits_add_no!3(f, 1);
3227 g.class_subclasses[j] = get_bits!2(f);
3228 if (g.class_subclasses[j]) {
3229 g.class_masterbooks[j] = get_bits!8(f);
3230 if (g.class_masterbooks[j] >= f.codebook_count) return error(f, STBVorbisError.invalid_setup);
3232 foreach (immutable k; 0..1<<g.class_subclasses[j]) {
3233 g.subclass_books[j].ptr[k] = get_bits!8(f)-1;
3234 if (g.subclass_books[j].ptr[k] >= f.codebook_count) return error(f, STBVorbisError.invalid_setup);
3237 g.floor1_multiplier = get_bits_add_no!2(f, 1);
3238 g.rangebits = get_bits!4(f);
3239 g.Xlist[0] = 0;
3240 g.Xlist[1] = cast(ushort)(1<<g.rangebits); //k8
3241 g.values = 2;
3242 foreach (immutable j; 0..g.partitions) {
3243 int c = g.partition_class_list[j];
3244 foreach (immutable k; 0..g.class_dimensions[c]) {
3245 g.Xlist[g.values] = cast(ushort)get_bits_main(f, g.rangebits); //k8
3246 ++g.values;
3249 assert(g.values <= ushort.max);
3250 // precompute the sorting
3251 foreach (ushort j; 0..cast(ushort)g.values) {
3252 p[j].x = g.Xlist[j];
3253 p[j].y = j;
3255 qsort(p.ptr, g.values, (p[0]).sizeof, &point_compare);
3256 foreach (uint j; 0..g.values) g.sorted_order.ptr[j] = cast(ubyte)p.ptr[j].y;
3257 // precompute the neighbors
3258 foreach (uint j; 2..g.values) {
3259 ushort low = void, hi = void;
3260 neighbors(g.Xlist.ptr, j, &low, &hi);
3261 assert(low <= ubyte.max);
3262 assert(hi <= ubyte.max);
3263 g.neighbors[j].ptr[0] = cast(ubyte)low;
3264 g.neighbors[j].ptr[1] = cast(ubyte)hi;
3266 if (g.values > longest_floorlist) longest_floorlist = g.values;
3270 // Residue
3271 f.residue_count = get_bits_add_no!6(f, 1);
3272 f.residue_config = setup_malloc!Residue(f, f.residue_count);
3273 if (f.residue_config is null) return error(f, STBVorbisError.outofmem);
3274 memset(f.residue_config, 0, f.residue_count*(f.residue_config[0]).sizeof);
3275 foreach (immutable i; 0..f.residue_count) {
3276 ubyte[64] residue_cascade;
3277 Residue* r = f.residue_config+i;
3278 f.residue_types[i] = get_bits!16(f);
3279 if (f.residue_types[i] > 2) return error(f, STBVorbisError.invalid_setup);
3280 r.begin = get_bits!24(f);
3281 r.end = get_bits!24(f);
3282 if (r.end < r.begin) return error(f, STBVorbisError.invalid_setup);
3283 r.part_size = get_bits_add_no!24(f, 1);
3284 r.classifications = get_bits_add_no!6(f, 1);
3285 r.classbook = get_bits!8(f);
3286 if (r.classbook >= f.codebook_count) return error(f, STBVorbisError.invalid_setup);
3287 foreach (immutable j; 0..r.classifications) {
3288 ubyte high_bits = 0;
3289 ubyte low_bits = get_bits!3(f);
3290 if (get_bits!1(f)) high_bits = get_bits!5(f);
3291 assert(high_bits*8+low_bits <= ubyte.max);
3292 residue_cascade[j] = cast(ubyte)(high_bits*8+low_bits);
3294 static assert(r.residue_books[0].sizeof == 16);
3295 r.residue_books = setup_malloc!(short[8])(f, r.classifications);
3296 if (r.residue_books is null) return error(f, STBVorbisError.outofmem);
3297 foreach (immutable j; 0..r.classifications) {
3298 foreach (immutable k; 0..8) {
3299 if (residue_cascade[j]&(1<<k)) {
3300 r.residue_books[j].ptr[k] = get_bits!8(f);
3301 if (r.residue_books[j].ptr[k] >= f.codebook_count) return error(f, STBVorbisError.invalid_setup);
3302 } else {
3303 r.residue_books[j].ptr[k] = -1;
3307 // precompute the classifications[] array to avoid inner-loop mod/divide
3308 // call it 'classdata' since we already have r.classifications
3309 r.classdata = setup_malloc!(ubyte*)(f, f.codebooks[r.classbook].entries);
3310 if (!r.classdata) return error(f, STBVorbisError.outofmem);
3311 memset(r.classdata, 0, (*r.classdata).sizeof*f.codebooks[r.classbook].entries);
3312 foreach (immutable j; 0..f.codebooks[r.classbook].entries) {
3313 int classwords = f.codebooks[r.classbook].dimensions;
3314 int temp = j;
3315 r.classdata[j] = setup_malloc!ubyte(f, classwords);
3316 if (r.classdata[j] is null) return error(f, STBVorbisError.outofmem);
3317 foreach_reverse (immutable k; 0..classwords) {
3318 assert(temp%r.classifications >= 0 && temp%r.classifications <= ubyte.max);
3319 r.classdata[j][k] = cast(ubyte)(temp%r.classifications);
3320 temp /= r.classifications;
3325 f.mapping_count = get_bits_add_no!6(f, 1);
3326 f.mapping = setup_malloc!Mapping(f, f.mapping_count);
3327 if (f.mapping is null) return error(f, STBVorbisError.outofmem);
3328 memset(f.mapping, 0, f.mapping_count*(*f.mapping).sizeof);
3329 foreach (immutable i; 0..f.mapping_count) {
3330 Mapping* m = f.mapping+i;
3331 int mapping_type = get_bits!16(f);
3332 if (mapping_type != 0) return error(f, STBVorbisError.invalid_setup);
3333 m.chan = setup_malloc!MappingChannel(f, f.vrchannels);
3334 if (m.chan is null) return error(f, STBVorbisError.outofmem);
3335 m.submaps = (get_bits!1(f) ? get_bits_add_no!4(f, 1) : 1);
3336 if (m.submaps > max_submaps) max_submaps = m.submaps;
3337 if (get_bits!1(f)) {
3338 m.coupling_steps = get_bits_add_no!8(f, 1);
3339 foreach (immutable k; 0..m.coupling_steps) {
3340 m.chan[k].magnitude = cast(ubyte)get_bits_main(f, ilog(f.vrchannels-1)); //k8
3341 m.chan[k].angle = cast(ubyte)get_bits_main(f, ilog(f.vrchannels-1)); //k8
3342 if (m.chan[k].magnitude >= f.vrchannels) return error(f, STBVorbisError.invalid_setup);
3343 if (m.chan[k].angle >= f.vrchannels) return error(f, STBVorbisError.invalid_setup);
3344 if (m.chan[k].magnitude == m.chan[k].angle) return error(f, STBVorbisError.invalid_setup);
3346 } else {
3347 m.coupling_steps = 0;
3350 // reserved field
3351 if (get_bits!2(f)) return error(f, STBVorbisError.invalid_setup);
3352 if (m.submaps > 1) {
3353 foreach (immutable j; 0..f.vrchannels) {
3354 m.chan[j].mux = get_bits!4(f);
3355 if (m.chan[j].mux >= m.submaps) return error(f, STBVorbisError.invalid_setup);
3357 } else {
3358 // @SPECIFICATION: this case is missing from the spec
3359 foreach (immutable j; 0..f.vrchannels) m.chan[j].mux = 0;
3361 foreach (immutable j; 0..m.submaps) {
3362 get_bits!8(f); // discard
3363 m.submap_floor[j] = get_bits!8(f);
3364 m.submap_residue[j] = get_bits!8(f);
3365 if (m.submap_floor[j] >= f.floor_count) return error(f, STBVorbisError.invalid_setup);
3366 if (m.submap_residue[j] >= f.residue_count) return error(f, STBVorbisError.invalid_setup);
3370 // Modes
3371 f.mode_count = get_bits_add_no!6(f, 1);
3372 foreach (immutable i; 0..f.mode_count) {
3373 Mode* m = f.mode_config.ptr+i;
3374 m.blockflag = get_bits!1(f);
3375 m.windowtype = get_bits!16(f);
3376 m.transformtype = get_bits!16(f);
3377 m.mapping = get_bits!8(f);
3378 if (m.windowtype != 0) return error(f, STBVorbisError.invalid_setup);
3379 if (m.transformtype != 0) return error(f, STBVorbisError.invalid_setup);
3380 if (m.mapping >= f.mapping_count) return error(f, STBVorbisError.invalid_setup);
3383 flush_packet(f);
3385 f.previous_length = 0;
3387 foreach (immutable i; 0..f.vrchannels) {
3388 f.channel_buffers.ptr[i] = setup_malloc!float(f, f.blocksize_1);
3389 f.previous_window.ptr[i] = setup_malloc!float(f, f.blocksize_1/2);
3390 f.finalY.ptr[i] = setup_malloc!short(f, longest_floorlist);
3391 if (f.channel_buffers.ptr[i] is null || f.previous_window.ptr[i] is null || f.finalY.ptr[i] is null) return error(f, STBVorbisError.outofmem);
3392 version(STB_VORBIS_NO_DEFER_FLOOR) {
3393 f.floor_buffers.ptr[i] = setup_malloc!float(f, f.blocksize_1/2);
3394 if (f.floor_buffers.ptr[i] is null) return error(f, STBVorbisError.outofmem);
3398 if (!init_blocksize(f, 0, f.blocksize_0)) return false;
3399 if (!init_blocksize(f, 1, f.blocksize_1)) return false;
3400 f.blocksize.ptr[0] = f.blocksize_0;
3401 f.blocksize.ptr[1] = f.blocksize_1;
3403 version(STB_VORBIS_DIVIDE_TABLE) {
3404 if (integer_divide_table[1].ptr[1] == 0) {
3405 foreach (immutable i; 0..DIVTAB_NUMER) foreach (immutable j; 1..DIVTAB_DENOM) integer_divide_table[i].ptr[j] = i/j;
3409 // compute how much temporary memory is needed
3411 // 1.
3413 uint imdct_mem = (f.blocksize_1*cast(uint)(float).sizeof>>1);
3414 uint classify_mem;
3415 int max_part_read = 0;
3416 foreach (immutable i; 0..f.residue_count) {
3417 Residue* r = f.residue_config+i;
3418 int n_read = r.end-r.begin;
3419 int part_read = n_read/r.part_size;
3420 if (part_read > max_part_read) max_part_read = part_read;
3422 version(STB_VORBIS_DIVIDES_IN_RESIDUE) {
3423 classify_mem = f.vrchannels*cast(uint)((void*).sizeof+max_part_read*(int*).sizeof);
3424 } else {
3425 classify_mem = f.vrchannels*cast(uint)((void*).sizeof+max_part_read*(ubyte*).sizeof);
3427 f.temp_memory_required = classify_mem;
3428 if (imdct_mem > f.temp_memory_required) f.temp_memory_required = imdct_mem;
3431 f.first_decode = true;
3434 if (f.alloc.alloc_buffer) {
3435 debug(stb_vorbis) assert(f.temp_offset == f.alloc.alloc_buffer_length_in_bytes);
3436 // check if there's enough temp memory so we don't error later
3437 if (f.setup_offset+ /*(*f).sizeof+*/ f.temp_memory_required > cast(uint)f.temp_offset) return error(f, STBVorbisError.outofmem);
3441 f.first_audio_page_offset = f.fileOffset();
3443 return true;
3447 private int vorbis_search_for_page_pushdata (VorbisDecoder f, ubyte* data, int data_len) {
3448 import core.stdc.string : memcmp;
3450 foreach (immutable i; 0..f.page_crc_tests) f.scan.ptr[i].bytes_done = 0;
3452 // if we have room for more scans, search for them first, because
3453 // they may cause us to stop early if their header is incomplete
3454 if (f.page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) {
3455 if (data_len < 4) return 0;
3456 data_len -= 3; // need to look for 4-byte sequence, so don't miss one that straddles a boundary
3457 foreach (immutable i; 0..data_len) {
3458 if (data[i] == 0x4f) {
3459 if (memcmp(data+i, ogg_page_header.ptr, 4) == 0) {
3460 // make sure we have the whole page header
3461 if (i+26 >= data_len || i+27+data[i+26] >= data_len) {
3462 // only read up to this page start, so hopefully we'll
3463 // have the whole page header start next time
3464 data_len = i;
3465 break;
3467 // ok, we have it all; compute the length of the page
3468 auto len = 27+data[i+26];
3469 foreach (immutable j; 0..data[i+26]) len += data[i+27+j];
3470 // scan everything up to the embedded crc (which we must 0)
3471 uint crc = 0;
3472 foreach (immutable j; 0..22) crc = crc32_update(crc, data[i+j]);
3473 // now process 4 0-bytes
3474 foreach (immutable j; 22..26) crc = crc32_update(crc, 0);
3475 // len is the total number of bytes we need to scan
3476 auto n = f.page_crc_tests++;
3477 f.scan.ptr[n].bytes_left = len-/*j*/26;
3478 f.scan.ptr[n].crc_so_far = crc;
3479 f.scan.ptr[n].goal_crc = data[i+22]+(data[i+23]<<8)+(data[i+24]<<16)+(data[i+25]<<24);
3480 // if the last frame on a page is continued to the next, then
3481 // we can't recover the sample_loc immediately
3482 if (data[i+27+data[i+26]-1] == 255) {
3483 f.scan.ptr[n].sample_loc = ~0;
3484 } else {
3485 f.scan.ptr[n].sample_loc = data[i+6]+(data[i+7]<<8)+(data[i+8]<<16)+(data[i+9]<<24);
3487 f.scan.ptr[n].bytes_done = i+26/*j*/;
3488 if (f.page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT) break;
3489 // keep going if we still have room for more
3495 for (uint i = 0; i < f.page_crc_tests; ) {
3496 int nn = f.scan.ptr[i].bytes_done;
3497 int m = f.scan.ptr[i].bytes_left;
3498 if (m > data_len-nn) m = data_len-nn;
3499 // m is the bytes to scan in the current chunk
3500 uint crc = f.scan.ptr[i].crc_so_far;
3501 foreach (immutable j; 0..m) crc = crc32_update(crc, data[nn+j]);
3502 f.scan.ptr[i].bytes_left -= m;
3503 f.scan.ptr[i].crc_so_far = crc;
3504 if (f.scan.ptr[i].bytes_left == 0) {
3505 // does it match?
3506 if (f.scan.ptr[i].crc_so_far == f.scan.ptr[i].goal_crc) {
3507 // Houston, we have page
3508 data_len = nn+m; // consumption amount is wherever that scan ended
3509 f.page_crc_tests = -1; // drop out of page scan mode
3510 f.previous_length = 0; // decode-but-don't-output one frame
3511 f.next_seg = -1; // start a new page
3512 f.current_loc = f.scan.ptr[i].sample_loc; // set the current sample location to the amount we'd have decoded had we decoded this page
3513 f.current_loc_valid = f.current_loc != ~0U;
3514 return data_len;
3516 // delete entry
3517 f.scan.ptr[i] = f.scan.ptr[--f.page_crc_tests];
3518 } else {
3519 ++i;
3523 return data_len;
3527 private uint vorbis_find_page (VorbisDecoder f, uint* end, uint* last) {
3528 for (;;) {
3529 if (f.eof) return 0;
3530 auto n = get8(f);
3531 if (n == 0x4f) { // page header candidate
3532 uint retry_loc = f.fileOffset;
3533 // check if we're off the end of a file_section stream
3534 if (retry_loc-25 > f.stream_len) return 0;
3535 // check the rest of the header
3536 int i = void;
3537 for (i = 1; i < 4; ++i) if (get8(f) != ogg_page_header[i]) break;
3538 if (f.eof) return 0;
3539 if (i == 4) {
3540 ubyte[27] header;
3541 //for (i=0; i < 4; ++i) header[i] = ogg_page_header[i];
3542 header[0..4] = cast(immutable(ubyte)[])ogg_page_header[0..4];
3543 for (i = 4; i < 27; ++i) header[i] = get8(f);
3544 if (f.eof) return 0;
3545 if (header[4] != 0) goto invalid;
3546 uint goal = header[22]+(header[23]<<8)+(header[24]<<16)+(header[25]<<24);
3547 for (i = 22; i < 26; ++i) header[i] = 0;
3548 uint crc = 0;
3549 for (i = 0; i < 27; ++i) crc = crc32_update(crc, header[i]);
3550 uint len = 0;
3551 for (i = 0; i < header[26]; ++i) {
3552 auto s = get8(f);
3553 crc = crc32_update(crc, s);
3554 len += s;
3556 if (len && f.eof) return 0;
3557 for (i = 0; i < len; ++i) crc = crc32_update(crc, get8(f));
3558 // finished parsing probable page
3559 if (crc == goal) {
3560 // we could now check that it's either got the last
3561 // page flag set, OR it's followed by the capture
3562 // pattern, but I guess TECHNICALLY you could have
3563 // a file with garbage between each ogg page and recover
3564 // from it automatically? So even though that paranoia
3565 // might decrease the chance of an invalid decode by
3566 // another 2^32, not worth it since it would hose those
3567 // invalid-but-useful files?
3568 if (end) *end = f.fileOffset;
3569 if (last) *last = (header[5]&0x04 ? 1 : 0);
3570 set_file_offset(f, retry_loc-1);
3571 return 1;
3574 invalid:
3575 // not a valid page, so rewind and look for next one
3576 set_file_offset(f, retry_loc);
3579 assert(0);
3582 enum SAMPLE_unknown = 0xffffffff;
3584 // seeking is implemented with a binary search, which narrows down the range to
3585 // 64K, before using a linear search (because finding the synchronization
3586 // pattern can be expensive, and the chance we'd find the end page again is
3587 // relatively high for small ranges)
3589 // two initial interpolation-style probes are used at the start of the search
3590 // to try to bound either side of the binary search sensibly, while still
3591 // working in O(log n) time if they fail.
3592 private int get_seek_page_info (VorbisDecoder f, ProbedPage* z) {
3593 ubyte[27] header;
3594 ubyte[255] lacing;
3596 // record where the page starts
3597 z.page_start = f.fileOffset;
3599 // parse the header
3600 getn(f, header.ptr, 27);
3601 if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S') return 0;
3602 getn(f, lacing.ptr, header[26]);
3604 // determine the length of the payload
3605 uint len = 0;
3606 foreach (immutable i; 0..header[26]) len += lacing[i];
3608 // this implies where the page ends
3609 z.page_end = z.page_start+27+header[26]+len;
3611 // read the last-decoded sample out of the data
3612 z.last_decoded_sample = header[6]+(header[7]<<8)+(header[8]<<16)+(header[9]<<24);
3614 // restore file state to where we were
3615 set_file_offset(f, z.page_start);
3616 return 1;
3619 // rarely used function to seek back to the preceeding page while finding the start of a packet
3620 private int go_to_page_before (VorbisDecoder f, uint limit_offset) {
3621 uint previous_safe, end;
3623 // now we want to seek back 64K from the limit
3624 if (limit_offset >= 65536 && limit_offset-65536 >= f.first_audio_page_offset) {
3625 previous_safe = limit_offset-65536;
3626 } else {
3627 previous_safe = f.first_audio_page_offset;
3630 set_file_offset(f, previous_safe);
3632 while (vorbis_find_page(f, &end, null)) {
3633 if (end >= limit_offset && f.fileOffset < limit_offset) return 1;
3634 set_file_offset(f, end);
3637 return 0;
3640 // implements the search logic for finding a page and starting decoding. if
3641 // the function succeeds, current_loc_valid will be true and current_loc will
3642 // be less than or equal to the provided sample number (the closer the
3643 // better).
3644 private int seek_to_sample_coarse (VorbisDecoder f, uint sample_number) {
3645 ProbedPage left, right, mid;
3646 int i, start_seg_with_known_loc, end_pos, page_start;
3647 uint delta, stream_length, padding;
3648 double offset, bytes_per_sample;
3649 int probe = 0;
3651 // find the last page and validate the target sample
3652 stream_length = f.streamLengthInSamples;
3653 if (stream_length == 0) return error(f, STBVorbisError.seek_without_length);
3654 if (sample_number > stream_length) return error(f, STBVorbisError.seek_invalid);
3656 // this is the maximum difference between the window-center (which is the
3657 // actual granule position value), and the right-start (which the spec
3658 // indicates should be the granule position (give or take one)).
3659 padding = ((f.blocksize_1-f.blocksize_0)>>2);
3660 if (sample_number < padding) sample_number = 0; else sample_number -= padding;
3662 left = f.p_first;
3663 while (left.last_decoded_sample == ~0U) {
3664 // (untested) the first page does not have a 'last_decoded_sample'
3665 set_file_offset(f, left.page_end);
3666 if (!get_seek_page_info(f, &left)) goto error;
3669 right = f.p_last;
3670 debug(stb_vorbis) assert(right.last_decoded_sample != ~0U);
3672 // starting from the start is handled differently
3673 if (sample_number <= left.last_decoded_sample) {
3674 f.seekStart;
3675 return 1;
3678 while (left.page_end != right.page_start) {
3679 debug(stb_vorbis) assert(left.page_end < right.page_start);
3680 // search range in bytes
3681 delta = right.page_start-left.page_end;
3682 if (delta <= 65536) {
3683 // there's only 64K left to search - handle it linearly
3684 set_file_offset(f, left.page_end);
3685 } else {
3686 if (probe < 2) {
3687 if (probe == 0) {
3688 // first probe (interpolate)
3689 double data_bytes = right.page_end-left.page_start;
3690 bytes_per_sample = data_bytes/right.last_decoded_sample;
3691 offset = left.page_start+bytes_per_sample*(sample_number-left.last_decoded_sample);
3692 } else {
3693 // second probe (try to bound the other side)
3694 double error = (cast(double)sample_number-mid.last_decoded_sample)*bytes_per_sample;
3695 if (error >= 0 && error < 8000) error = 8000;
3696 if (error < 0 && error > -8000) error = -8000;
3697 offset += error*2;
3700 // ensure the offset is valid
3701 if (offset < left.page_end) offset = left.page_end;
3702 if (offset > right.page_start-65536) offset = right.page_start-65536;
3704 set_file_offset(f, cast(uint)offset);
3705 } else {
3706 // binary search for large ranges (offset by 32K to ensure
3707 // we don't hit the right page)
3708 set_file_offset(f, left.page_end+(delta/2)-32768);
3711 if (!vorbis_find_page(f, null, null)) goto error;
3714 for (;;) {
3715 if (!get_seek_page_info(f, &mid)) goto error;
3716 if (mid.last_decoded_sample != ~0U) break;
3717 // (untested) no frames end on this page
3718 set_file_offset(f, mid.page_end);
3719 debug(stb_vorbis) assert(mid.page_start < right.page_start);
3722 // if we've just found the last page again then we're in a tricky file,
3723 // and we're close enough.
3724 if (mid.page_start == right.page_start) break;
3726 if (sample_number < mid.last_decoded_sample) right = mid; else left = mid;
3728 ++probe;
3731 // seek back to start of the last packet
3732 page_start = left.page_start;
3733 set_file_offset(f, page_start);
3734 if (!start_page(f)) return error(f, STBVorbisError.seek_failed);
3735 end_pos = f.end_seg_with_known_loc;
3736 debug(stb_vorbis) assert(end_pos >= 0);
3738 for (;;) {
3739 for (i = end_pos; i > 0; --i) if (f.segments.ptr[i-1] != 255) break;
3740 start_seg_with_known_loc = i;
3741 if (start_seg_with_known_loc > 0 || !(f.page_flag&PAGEFLAG_continued_packet)) break;
3742 // (untested) the final packet begins on an earlier page
3743 if (!go_to_page_before(f, page_start)) goto error;
3744 page_start = f.fileOffset;
3745 if (!start_page(f)) goto error;
3746 end_pos = f.segment_count-1;
3749 // prepare to start decoding
3750 f.current_loc_valid = false;
3751 f.last_seg = false;
3752 f.valid_bits = 0;
3753 f.packet_bytes = 0;
3754 f.bytes_in_seg = 0;
3755 f.previous_length = 0;
3756 f.next_seg = start_seg_with_known_loc;
3758 for (i = 0; i < start_seg_with_known_loc; ++i) skip(f, f.segments.ptr[i]);
3760 // start decoding (optimizable - this frame is generally discarded)
3761 if (!vorbis_pump_first_frame(f)) return 0;
3762 if (f.current_loc > sample_number) return error(f, STBVorbisError.seek_failed);
3763 return 1;
3765 error:
3766 // try to restore the file to a valid state
3767 f.seekStart;
3768 return error(f, STBVorbisError.seek_failed);
3771 // the same as vorbis_decode_initial, but without advancing
3772 private int peek_decode_initial (VorbisDecoder f, int* p_left_start, int* p_left_end, int* p_right_start, int* p_right_end, int* mode) {
3773 if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode)) return 0;
3775 // either 1 or 2 bytes were read, figure out which so we can rewind
3776 int bits_read = 1+ilog(f.mode_count-1);
3777 if (f.mode_config.ptr[*mode].blockflag) bits_read += 2;
3778 int bytes_read = (bits_read+7)/8;
3780 f.bytes_in_seg += bytes_read;
3781 f.packet_bytes -= bytes_read;
3782 skip(f, -bytes_read);
3783 if (f.next_seg == -1) f.next_seg = f.segment_count-1; else --f.next_seg;
3784 f.valid_bits = 0;
3786 return 1;
3789 // ////////////////////////////////////////////////////////////////////////// //
3790 // utility and supporting functions for getting s16 samples
3791 enum PLAYBACK_MONO = (1<<0);
3792 enum PLAYBACK_LEFT = (1<<1);
3793 enum PLAYBACK_RIGHT = (1<<2);
3795 enum L = (PLAYBACK_LEFT |PLAYBACK_MONO);
3796 enum C = (PLAYBACK_LEFT |PLAYBACK_RIGHT|PLAYBACK_MONO);
3797 enum R = (PLAYBACK_RIGHT|PLAYBACK_MONO);
3799 immutable byte[6][7] channel_position = [
3800 [ 0 ],
3801 [ C ],
3802 [ L, R ],
3803 [ L, C, R ],
3804 [ L, R, L, R ],
3805 [ L, C, R, L, R ],
3806 [ L, C, R, L, R, C ],
3810 version(STB_VORBIS_NO_FAST_SCALED_FLOAT) {
3811 enum declfcvar(string name) = "{}";
3812 template FAST_SCALED_FLOAT_TO_INT(string x, string s) {
3813 static assert(s == "15");
3814 enum FAST_SCALED_FLOAT_TO_INT = q{import core.stdc.math : lrintf; int v = lrintf((${x})*32768.0f);}.cmacroFixVars!"x"(x);
3816 } else {
3817 //k8: actually, this is only marginally faster than using `lrintf()`, but anyway...
3818 align(1) union float_conv {
3819 align(1):
3820 float f;
3821 int i;
3823 enum declfcvar(string name) = "float_conv "~name~" = void;";
3824 static assert(float_conv.i.sizeof == 4 && float_conv.f.sizeof == 4);
3825 // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round
3826 //#define check_endianness()
3827 enum MAGIC(string SHIFT) = q{(1.5f*(1<<(23-${SHIFT}))+0.5f/(1<<${SHIFT}))}.cmacroFixVars!("SHIFT")(SHIFT);
3828 enum ADDEND(string SHIFT) = q{(((150-${SHIFT})<<23)+(1<<22))}.cmacroFixVars!("SHIFT")(SHIFT);
3829 enum FAST_SCALED_FLOAT_TO_INT(string x, string s) = q{temp.f = (${x})+${MAGIC}; int v = temp.i-${ADDEND};}
3830 .cmacroFixVars!("x", "s", "MAGIC", "ADDEND")(x, s, MAGIC!(s), ADDEND!(s));
3833 private void copy_samples (short* dest, float* src, int len) {
3834 //check_endianness();
3835 mixin(declfcvar!"temp");
3836 foreach (immutable _; 0..len) {
3837 mixin(FAST_SCALED_FLOAT_TO_INT!("*src", "15"));
3838 if (cast(uint)(v+32768) > 65535) v = (v < 0 ? -32768 : 32767);
3839 *dest++ = cast(short)v; //k8
3840 ++src;
3844 private void compute_samples (int mask, short* output, int num_c, float** data, int d_offset, int len) {
3845 import core.stdc.string : memset;
3846 enum BUFFER_SIZE = 32;
3847 float[BUFFER_SIZE] buffer;
3848 int n = BUFFER_SIZE;
3849 //check_endianness();
3850 mixin(declfcvar!"temp");
3851 for (uint o = 0; o < len; o += BUFFER_SIZE) {
3852 memset(buffer.ptr, 0, (buffer).sizeof);
3853 if (o+n > len) n = len-o;
3854 foreach (immutable j; 0..num_c) {
3855 if (channel_position[num_c].ptr[j]&mask) foreach (immutable i; 0..n) buffer.ptr[i] += data[j][d_offset+o+i];
3857 foreach (immutable i; 0..n) {
3858 mixin(FAST_SCALED_FLOAT_TO_INT!("buffer[i]", "15"));
3859 if (cast(uint)(v+32768) > 65535) v = (v < 0 ? -32768 : 32767);
3860 output[o+i] = cast(short)v; //k8
3865 private void compute_stereo_samples (short* output, int num_c, float** data, int d_offset, int len) {
3866 import core.stdc.string : memset;
3868 enum BUFFER_SIZE = 32;
3869 float[BUFFER_SIZE] buffer;
3870 int n = BUFFER_SIZE>>1;
3871 // o is the offset in the source data
3872 //check_endianness();
3873 mixin(declfcvar!"temp");
3874 for (uint o = 0; o < len; o += BUFFER_SIZE>>1) {
3875 // o2 is the offset in the output data
3876 int o2 = o<<1;
3877 memset(buffer.ptr, 0, buffer.sizeof);
3878 if (o+n > len) n = len-o;
3879 foreach (immutable j; 0..num_c) {
3880 int m = channel_position[num_c].ptr[j]&(PLAYBACK_LEFT|PLAYBACK_RIGHT);
3881 if (m == (PLAYBACK_LEFT|PLAYBACK_RIGHT)) {
3882 foreach (immutable i; 0..n) {
3883 buffer.ptr[i*2+0] += data[j][d_offset+o+i];
3884 buffer.ptr[i*2+1] += data[j][d_offset+o+i];
3886 } else if (m == PLAYBACK_LEFT) {
3887 foreach (immutable i; 0..n) buffer.ptr[i*2+0] += data[j][d_offset+o+i];
3888 } else if (m == PLAYBACK_RIGHT) {
3889 foreach (immutable i; 0..n) buffer.ptr[i*2+1] += data[j][d_offset+o+i];
3892 foreach (immutable i; 0..n<<1) {
3893 mixin(FAST_SCALED_FLOAT_TO_INT!("buffer[i]", "15"));
3894 if (cast(uint)(v+32768) > 65535) v = (v < 0 ? -32768 : 32767);
3895 output[o2+i] = cast(short)v; //k8
3900 private void convert_samples_short (int buf_c, short** buffer, int b_offset, int data_c, float** data, int d_offset, int samples) {
3901 import core.stdc.string : memset;
3903 if (buf_c != data_c && buf_c <= 2 && data_c <= 6) {
3904 immutable int[2][3] channel_selector = [ [0,0], [PLAYBACK_MONO,0], [PLAYBACK_LEFT, PLAYBACK_RIGHT] ];
3905 foreach (immutable i; 0..buf_c) compute_samples(channel_selector[buf_c].ptr[i], buffer[i]+b_offset, data_c, data, d_offset, samples);
3906 } else {
3907 int limit = (buf_c < data_c ? buf_c : data_c);
3908 foreach (immutable i; 0..limit) copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples);
3909 foreach (immutable i; limit..buf_c) memset(buffer[i]+b_offset, 0, short.sizeof*samples);
3913 private void convert_channels_short_interleaved (int buf_c, short* buffer, int data_c, float** data, int d_offset, int len) {
3914 //check_endianness();
3915 mixin(declfcvar!"temp");
3916 if (buf_c != data_c && buf_c <= 2 && data_c <= 6) {
3917 debug(stb_vorbis) assert(buf_c == 2);
3918 foreach (immutable i; 0..buf_c) compute_stereo_samples(buffer, data_c, data, d_offset, len);
3919 } else {
3920 int limit = (buf_c < data_c ? buf_c : data_c);
3921 foreach (immutable j; 0..len) {
3922 foreach (immutable i; 0..limit) {
3923 float f = data[i][d_offset+j];
3924 mixin(FAST_SCALED_FLOAT_TO_INT!("f", "15"));//data[i][d_offset+j], 15);
3925 if (cast(uint)(v+32768) > 65535) v = (v < 0 ? -32768 : 32767);
3926 *buffer++ = cast(short)v; //k8
3928 foreach (immutable i; limit..buf_c) *buffer++ = 0;
3932 } // @nogc
3935 public class VorbisDecoder {
3936 // return # of bytes read, 0 on eof, -1 on error
3937 // if called with `buf is null`, do `close()`
3938 alias readCB = int delegate (void[] buf, uint ofs, VorbisDecoder vb) nothrow @nogc;
3940 //TODO
3941 static struct Allocator {
3942 static nothrow @nogc: // because
3943 void* alloc (uint sz, VorbisDecoder vb) {
3944 import core.stdc.stdlib : malloc;
3945 return malloc(sz);
3947 void free (void* p, VorbisDecoder vb) {
3948 import core.stdc.stdlib : free;
3949 free(p);
3951 void* allocTemp (uint sz, VorbisDecoder vb) {
3952 import core.stdc.stdlib : malloc;
3953 return malloc(sz);
3955 void freeTemp (void* p, uint sz, VorbisDecoder vb) {
3956 import core.stdc.stdlib : free;
3957 free(p);
3959 uint tempSave (VorbisDecoder vb) { return 0; }
3960 void tempRestore (uint pos, VorbisDecoder vb) {}
3963 nothrow @nogc:
3964 private:
3965 bool isOpened;
3966 readCB stmread;
3967 uint stlastofs = uint.max;
3968 uint stst;
3969 uint stpos;
3970 uint stend;
3971 bool stclose;
3972 FILE* stfl;
3974 private:
3975 //ubyte* stream;
3976 //ubyte* stream_start;
3977 //ubyte* stream_end;
3978 //uint stream_len;
3980 /+bool push_mode;+/
3982 uint first_audio_page_offset;
3984 ProbedPage p_first, p_last;
3986 // memory management
3987 Allocator alloc;
3988 int setup_offset;
3989 int temp_offset;
3991 // run-time results
3992 bool eof = true;
3993 STBVorbisError error;
3995 // header info
3996 int[2] blocksize;
3997 int blocksize_0, blocksize_1;
3998 int codebook_count;
3999 Codebook* codebooks;
4000 int floor_count;
4001 ushort[64] floor_types; // varies
4002 Floor* floor_config;
4003 int residue_count;
4004 ushort[64] residue_types; // varies
4005 Residue* residue_config;
4006 int mapping_count;
4007 Mapping* mapping;
4008 int mode_count;
4009 Mode[64] mode_config; // varies
4011 uint total_samples;
4013 // decode buffer
4014 float*[STB_VORBIS_MAX_CHANNELS] channel_buffers;
4015 float*[STB_VORBIS_MAX_CHANNELS] outputs;
4017 float*[STB_VORBIS_MAX_CHANNELS] previous_window;
4018 int previous_length;
4020 version(STB_VORBIS_NO_DEFER_FLOOR) {
4021 float*[STB_VORBIS_MAX_CHANNELS] floor_buffers;
4022 } else {
4023 short*[STB_VORBIS_MAX_CHANNELS] finalY;
4026 uint current_loc; // sample location of next frame to decode
4027 int current_loc_valid;
4029 // per-blocksize precomputed data
4031 // twiddle factors
4032 float*[2] A, B, C;
4033 float*[2] window;
4034 ushort*[2] bit_reverse;
4036 // current page/packet/segment streaming info
4037 uint serial; // stream serial number for verification
4038 int last_page;
4039 int segment_count;
4040 ubyte[255] segments;
4041 ubyte page_flag;
4042 ubyte bytes_in_seg;
4043 ubyte first_decode;
4044 int next_seg;
4045 int last_seg; // flag that we're on the last segment
4046 int last_seg_which; // what was the segment number of the last seg?
4047 uint acc;
4048 int valid_bits;
4049 int packet_bytes;
4050 int end_seg_with_known_loc;
4051 uint known_loc_for_packet;
4052 int discard_samples_deferred;
4053 uint samples_output;
4055 // push mode scanning
4057 int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching
4058 CRCscan[STB_VORBIS_PUSHDATA_CRC_COUNT] scan;
4061 // sample-access
4062 int channel_buffer_start;
4063 int channel_buffer_end;
4065 private: // k8: 'cause i'm evil
4066 // user-accessible info
4067 uint sample_rate;
4068 int vrchannels;
4070 uint setup_memory_required;
4071 uint temp_memory_required;
4072 uint setup_temp_memory_required;
4074 bool read_comments;
4075 ubyte* comment_data;
4076 uint comment_size;
4078 // functions to get comment data
4079 uint comment_data_pos;
4081 private:
4082 int rawRead (void[] buf) {
4083 static if (__VERSION__ > 2067) pragma(inline, true);
4084 if (isOpened && buf.length > 0 && stpos < stend) {
4085 if (stend-stpos < buf.length) buf = buf[0..stend-stpos];
4086 auto rd = stmread(buf, stpos, this);
4087 if (rd > 0) stpos += rd;
4088 return rd;
4090 return 0;
4092 void rawSkip (int n) { static if (__VERSION__ > 2067) pragma(inline, true); if (isOpened && n > 0) { if ((stpos += n) > stend) stpos = stend; } }
4093 void rawSeek (int n) { static if (__VERSION__ > 2067) pragma(inline, true); if (isOpened) { stpos = stst+(n < 0 ? 0 : n); if (stpos > stend) stpos = stend; } }
4094 void rawClose () { static if (__VERSION__ > 2067) pragma(inline, true); if (isOpened) { isOpened = false; stmread(null, 0, this); } }
4096 final:
4097 private:
4098 void doInit () {
4099 import core.stdc.string : memset;
4101 if (z) {
4102 alloc = *z;
4103 alloc.alloc_buffer_length_in_bytes = (alloc.alloc_buffer_length_in_bytes+3)&~3;
4104 temp_offset = alloc.alloc_buffer_length_in_bytes;
4107 eof = false;
4108 error = STBVorbisError.no_error;
4109 /+stream = null;+/
4110 codebooks = null;
4111 /+page_crc_tests = -1;+/
4114 static int stflRead (void[] buf, uint ofs, VorbisDecoder vb) {
4115 if (buf !is null) {
4116 //{ import core.stdc.stdio; printf("stflRead: ofs=%u; len=%u\n", ofs, cast(uint)buf.length); }
4117 if (vb.stlastofs != ofs) {
4118 import core.stdc.stdio : fseek, SEEK_SET;
4119 vb.stlastofs = ofs;
4120 fseek(vb.stfl, ofs, SEEK_SET);
4122 import core.stdc.stdio : fread;
4123 return cast(int)fread(buf.ptr, 1, buf.length, vb.stfl);
4124 } else {
4125 if (vb.stclose) {
4126 import core.stdc.stdio : fclose;
4127 if (vb.stfl !is null) fclose(vb.stfl);
4129 vb.stfl = null;
4130 return 0;
4134 public:
4135 this () {}
4136 ~this () { close(); }
4138 this (int asize, readCB rcb) { assert(rcb !is null); stend = (asize > 0 ? asize : 0); stmread = rcb; }
4139 this (FILE* fl, bool doclose=true) { open(fl, doclose); }
4140 this (const(char)[] filename) { open(filename); }
4142 @property bool closed () { return !isOpened; }
4144 void open (FILE *fl, bool doclose=true) {
4145 import core.stdc.stdio : ftell, fseek, SEEK_SET, SEEK_END;
4146 close();
4147 if (fl is null) { error = STBVorbisError.invalid_stream; return; }
4148 stclose = doclose;
4149 stst = stpos = cast(uint)ftell(fl);
4150 fseek(fl, 0, SEEK_END);
4151 stend = cast(uint)ftell(fl);
4152 stlastofs = stlastofs.max;
4153 stclose = false;
4154 stfl = fl;
4155 import std.functional : toDelegate;
4156 stmread = toDelegate(&stflRead);
4157 isOpened = true;
4158 eof = false;
4159 read_comments = true;
4160 if (start_decoder(this)) {
4161 vorbis_pump_first_frame(this);
4162 return;
4164 auto err = error;
4165 close();
4166 error = err;
4169 void open (const(char)[] filename) {
4170 import core.stdc.stdio : fopen;
4171 import std.internal.cstring; // sorry
4172 close();
4173 FILE* fl = fopen(filename.tempCString, "rb");
4174 if (fl is null) { error = STBVorbisError.file_open_failure; return; }
4175 open(fl, true);
4179 void openPushdata(void* data, int data_len, // the memory available for decoding
4180 int* data_used) // only defined on success
4182 close();
4183 eof = false;
4184 stream = cast(ubyte*)data;
4185 stream_end = stream+data_len;
4186 push_mode = true;
4187 if (!start_decoder(this)) {
4188 auto err = error;
4189 if (eof) err = STBVorbisError.need_more_data; else close();
4190 error = err;
4191 return;
4193 *data_used = stream-(cast(ubyte*)data);
4194 error = STBVorbisError.no_error;
4198 void close () {
4199 import core.stdc.string : memset;
4201 setup_free(this, this.comment_data);
4202 if (this.residue_config) {
4203 foreach (immutable i; 0..this.residue_count) {
4204 Residue* r = this.residue_config+i;
4205 if (r.classdata) {
4206 foreach (immutable j; 0..this.codebooks[r.classbook].entries) setup_free(this, r.classdata[j]);
4207 setup_free(this, r.classdata);
4209 setup_free(this, r.residue_books);
4213 if (this.codebooks) {
4214 foreach (immutable i; 0..this.codebook_count) {
4215 Codebook* c = this.codebooks+i;
4216 setup_free(this, c.codeword_lengths);
4217 setup_free(this, c.multiplicands);
4218 setup_free(this, c.codewords);
4219 setup_free(this, c.sorted_codewords);
4220 // c.sorted_values[-1] is the first entry in the array
4221 setup_free(this, c.sorted_values ? c.sorted_values-1 : null);
4223 setup_free(this, this.codebooks);
4225 setup_free(this, this.floor_config);
4226 setup_free(this, this.residue_config);
4227 if (this.mapping) {
4228 foreach (immutable i; 0..this.mapping_count) setup_free(this, this.mapping[i].chan);
4229 setup_free(this, this.mapping);
4231 foreach (immutable i; 0..(this.vrchannels > STB_VORBIS_MAX_CHANNELS ? STB_VORBIS_MAX_CHANNELS : this.vrchannels)) {
4232 setup_free(this, this.channel_buffers.ptr[i]);
4233 setup_free(this, this.previous_window.ptr[i]);
4234 version(STB_VORBIS_NO_DEFER_FLOOR) setup_free(this, this.floor_buffers.ptr[i]);
4235 setup_free(this, this.finalY.ptr[i]);
4237 foreach (immutable i; 0..2) {
4238 setup_free(this, this.A.ptr[i]);
4239 setup_free(this, this.B.ptr[i]);
4240 setup_free(this, this.C.ptr[i]);
4241 setup_free(this, this.window.ptr[i]);
4242 setup_free(this, this.bit_reverse.ptr[i]);
4245 rawClose();
4246 isOpened = false;
4247 stmread = null;
4248 stlastofs = uint.max;
4249 stst = 0;
4250 stpos = 0;
4251 stend = 0;
4252 stclose = false;
4253 stfl = null;
4255 sample_rate = 0;
4256 vrchannels = 0;
4258 setup_memory_required = 0;
4259 temp_memory_required = 0;
4260 setup_temp_memory_required = 0;
4262 read_comments = 0;
4263 comment_data = null;
4264 comment_size = 0;
4266 comment_data_pos = 0;
4269 stream = null;
4270 stream_start = null;
4271 stream_end = null;
4274 //stream_len = 0;
4276 /+push_mode = false;+/
4278 first_audio_page_offset = 0;
4280 p_first = p_first.init;
4281 p_last = p_last.init;
4283 setup_offset = 0;
4284 temp_offset = 0;
4286 eof = true;
4287 error = STBVorbisError.no_error;
4289 blocksize[] = 0;
4290 blocksize_0 = 0;
4291 blocksize_1 = 0;
4292 codebook_count = 0;
4293 codebooks = null;
4294 floor_count = 0;
4295 floor_types[] = 0;
4296 floor_config = null;
4297 residue_count = 0;
4298 residue_types[] = 0;
4299 residue_config = null;
4300 mapping_count = 0;
4301 mapping = null;
4302 mode_count = 0;
4303 mode_config[] = Mode.init;
4305 total_samples = 0;
4307 channel_buffers[] = null;
4308 outputs[] = null;
4310 previous_window[] = null;
4311 previous_length = 0;
4313 version(STB_VORBIS_NO_DEFER_FLOOR) {
4314 floor_buffers[] = null;
4315 } else {
4316 finalY[] = null;
4319 current_loc = 0;
4320 current_loc_valid = 0;
4322 A[] = null;
4323 B[] = null;
4324 C[] = null;
4325 window[] = null;
4326 bit_reverse = null;
4328 serial = 0;
4329 last_page = 0;
4330 segment_count = 0;
4331 segments[] = 0;
4332 page_flag = 0;
4333 bytes_in_seg = 0;
4334 first_decode = 0;
4335 next_seg = 0;
4336 last_seg = 0;
4337 last_seg_which = 0;
4338 acc = 0;
4339 valid_bits = 0;
4340 packet_bytes = 0;
4341 end_seg_with_known_loc = 0;
4342 known_loc_for_packet = 0;
4343 discard_samples_deferred = 0;
4344 samples_output = 0;
4347 page_crc_tests = -1;
4348 scan[] = CRCscan.init;
4351 channel_buffer_start = 0;
4352 channel_buffer_end = 0;
4355 @property const pure {
4356 int getSampleOffset () { return (current_loc_valid ? current_loc : -1); }
4358 @property ubyte chans () { return (isOpened ? cast(ubyte)this.vrchannels : 0); }
4359 @property uint sampleRate () { return (isOpened ? this.sample_rate : 0); }
4360 @property uint maxFrameSize () { return (isOpened ? this.blocksize_1>>1 : 0); }
4362 @property uint getSetupMemoryRequired () { return (isOpened ? this.setup_memory_required : 0); }
4363 @property uint getSetupTempMemoryRequired () { return (isOpened ? this.setup_temp_memory_required : 0); }
4364 @property uint getTempMemoryRequired () { return (isOpened ? this.temp_memory_required : 0); }
4367 // will clear last error
4368 @property int lastError () {
4369 int e = error;
4370 error = STBVorbisError.no_error;
4371 return e;
4374 // PUSHDATA API
4376 void flushPushdata () {
4377 if (push_mode) {
4378 previous_length = 0;
4379 page_crc_tests = 0;
4380 discard_samples_deferred = 0;
4381 current_loc_valid = false;
4382 first_decode = false;
4383 samples_output = 0;
4384 channel_buffer_start = 0;
4385 channel_buffer_end = 0;
4389 // return value: number of bytes we used
4390 int decodeFramePushdata(
4391 void* data, int data_len, // the memory available for decoding
4392 int* channels, // place to write number of float* buffers
4393 float*** output, // place to write float** array of float* buffers
4394 int* samples // place to write number of output samples
4397 if (!this.push_mode) return .error(this, STBVorbisError.invalid_api_mixing);
4399 if (this.page_crc_tests >= 0) {
4400 *samples = 0;
4401 return vorbis_search_for_page_pushdata(this, cast(ubyte*)data, data_len);
4404 this.stream = cast(ubyte*)data;
4405 this.stream_end = this.stream+data_len;
4406 this.error = STBVorbisError.no_error;
4408 // check that we have the entire packet in memory
4409 if (!is_whole_packet_present(this, false)) {
4410 *samples = 0;
4411 return 0;
4414 int len, left, right;
4416 if (!vorbis_decode_packet(this, &len, &left, &right)) {
4417 // save the actual error we encountered
4418 STBVorbisError error = this.error;
4419 if (error == STBVorbisError.bad_packet_type) {
4420 // flush and resynch
4421 this.error = STBVorbisError.no_error;
4422 while (get8_packet(this) != EOP) if (this.eof) break;
4423 *samples = 0;
4424 return this.stream-data;
4426 if (error == STBVorbisError.continued_packet_flag_invalid) {
4427 if (this.previous_length == 0) {
4428 // we may be resynching, in which case it's ok to hit one
4429 // of these; just discard the packet
4430 this.error = STBVorbisError.no_error;
4431 while (get8_packet(this) != EOP) if (this.eof) break;
4432 *samples = 0;
4433 return this.stream-data;
4436 // if we get an error while parsing, what to do?
4437 // well, it DEFINITELY won't work to continue from where we are!
4438 flushPushdata();
4439 // restore the error that actually made us bail
4440 this.error = error;
4441 *samples = 0;
4442 return 1;
4445 // success!
4446 len = vorbis_finish_frame(this, len, left, right);
4447 foreach (immutable i; 0..this.vrchannels) this.outputs.ptr[i] = this.channel_buffers.ptr[i]+left;
4449 if (channels) *channels = this.vrchannels;
4450 *samples = len;
4451 *output = this.outputs.ptr;
4452 return this.stream-data;
4456 public uint fileOffset () {
4457 if (/+push_mode ||+/ !isOpened) return 0;
4458 /+if (stream !is null) return cast(uint)(stream-stream_start);+/
4459 return (stpos > stst ? stpos-stst : 0);
4462 public uint stream_len () { return stend-stst; }
4464 // DATA-PULLING API
4465 public int seekFrame (uint sample_number) {
4466 uint max_frame_samples;
4468 /+if (this.push_mode) return -.error(this, STBVorbisError.invalid_api_mixing);+/
4470 // fast page-level search
4471 if (!seek_to_sample_coarse(this, sample_number)) return 0;
4473 assert(this.current_loc_valid);
4474 assert(this.current_loc <= sample_number);
4476 // linear search for the relevant packet
4477 max_frame_samples = (this.blocksize_1*3-this.blocksize_0)>>2;
4478 while (this.current_loc < sample_number) {
4479 int left_start, left_end, right_start, right_end, mode, frame_samples;
4480 if (!peek_decode_initial(this, &left_start, &left_end, &right_start, &right_end, &mode)) return .error(this, STBVorbisError.seek_failed);
4481 // calculate the number of samples returned by the next frame
4482 frame_samples = right_start-left_start;
4483 if (this.current_loc+frame_samples > sample_number) {
4484 return 1; // the next frame will contain the sample
4485 } else if (this.current_loc+frame_samples+max_frame_samples > sample_number) {
4486 // there's a chance the frame after this could contain the sample
4487 vorbis_pump_first_frame(this);
4488 } else {
4489 // this frame is too early to be relevant
4490 this.current_loc += frame_samples;
4491 this.previous_length = 0;
4492 maybe_start_packet(this);
4493 flush_packet(this);
4496 // the next frame will start with the sample
4497 assert(this.current_loc == sample_number);
4498 return 1;
4501 public int seek (uint sample_number) {
4502 if (!seekFrame(sample_number)) return 0;
4503 if (sample_number != this.current_loc) {
4504 int n;
4505 uint frame_start = this.current_loc;
4506 getFrameFloat(&n, null);
4507 assert(sample_number > frame_start);
4508 assert(this.channel_buffer_start+cast(int)(sample_number-frame_start) <= this.channel_buffer_end);
4509 this.channel_buffer_start += (sample_number-frame_start);
4511 return 1;
4514 public bool seekStart () {
4515 /+if (push_mode) { .error(this, STBVorbisError.invalid_api_mixing); return; }+/
4516 set_file_offset(this, first_audio_page_offset);
4517 previous_length = 0;
4518 first_decode = true;
4519 next_seg = -1;
4520 return vorbis_pump_first_frame(this);
4523 public uint streamLengthInSamples () {
4524 uint restore_offset, previous_safe;
4525 uint end, last_page_loc;
4527 /+if (this.push_mode) return .error(this, STBVorbisError.invalid_api_mixing);+/
4528 if (!this.total_samples) {
4529 uint last;
4530 uint lo, hi;
4531 char[6] header;
4533 // first, store the current decode position so we can restore it
4534 restore_offset = fileOffset;
4536 // now we want to seek back 64K from the end (the last page must
4537 // be at most a little less than 64K, but let's allow a little slop)
4538 if (this.stream_len >= 65536 && this.stream_len-65536 >= this.first_audio_page_offset) {
4539 previous_safe = this.stream_len-65536;
4540 } else {
4541 previous_safe = this.first_audio_page_offset;
4544 set_file_offset(this, previous_safe);
4545 // previous_safe is now our candidate 'earliest known place that seeking
4546 // to will lead to the final page'
4548 if (!vorbis_find_page(this, &end, &last)) {
4549 // if we can't find a page, we're hosed!
4550 this.error = STBVorbisError.cant_find_last_page;
4551 this.total_samples = 0xffffffff;
4552 goto done;
4555 // check if there are more pages
4556 last_page_loc = fileOffset;
4558 // stop when the last_page flag is set, not when we reach eof;
4559 // this allows us to stop short of a 'file_section' end without
4560 // explicitly checking the length of the section
4561 while (!last) {
4562 set_file_offset(this, end);
4563 if (!vorbis_find_page(this, &end, &last)) {
4564 // the last page we found didn't have the 'last page' flag set. whoops!
4565 break;
4567 previous_safe = last_page_loc+1;
4568 last_page_loc = fileOffset;
4571 set_file_offset(this, last_page_loc);
4573 // parse the header
4574 getn(this, cast(ubyte*)header, 6);
4575 // extract the absolute granule position
4576 lo = get32(this);
4577 hi = get32(this);
4578 if (lo == 0xffffffff && hi == 0xffffffff) {
4579 this.error = STBVorbisError.cant_find_last_page;
4580 this.total_samples = SAMPLE_unknown;
4581 goto done;
4583 if (hi) lo = 0xfffffffe; // saturate
4584 this.total_samples = lo;
4586 this.p_last.page_start = last_page_loc;
4587 this.p_last.page_end = end;
4588 this.p_last.last_decoded_sample = lo;
4590 done:
4591 set_file_offset(this, restore_offset);
4593 return (this.total_samples == SAMPLE_unknown ? 0 : this.total_samples);
4596 public float streamLengthInSeconds () {
4597 return (isOpened ? streamLengthInSamples()/cast(float)sample_rate : 0.0f);
4600 public int getFrameFloat (int* channels, float*** output) {
4601 int len, right, left;
4602 /+if (push_mode) return .error(this, STBVorbisError.invalid_api_mixing);+/
4604 if (!vorbis_decode_packet(this, &len, &left, &right)) {
4605 channel_buffer_start = channel_buffer_end = 0;
4606 return 0;
4609 len = vorbis_finish_frame(this, len, left, right);
4610 foreach (immutable i; 0..this.vrchannels) this.outputs.ptr[i] = this.channel_buffers.ptr[i]+left;
4612 channel_buffer_start = left;
4613 channel_buffer_end = left+len;
4615 if (channels) *channels = this.vrchannels;
4616 if (output) *output = this.outputs.ptr;
4617 return len;
4621 public VorbisDecoder stb_vorbis_open_memory (const(void)* data, int len, int* error=null, stb_vorbis_alloc* alloc=null) {
4622 VorbisDecoder this;
4623 stb_vorbis_ctx p = void;
4624 if (data is null) return null;
4625 vorbis_init(&p, alloc);
4626 p.stream = cast(ubyte*)data;
4627 p.stream_end = cast(ubyte*)data+len;
4628 p.stream_start = cast(ubyte*)p.stream;
4629 p.stream_len = len;
4630 p.push_mode = false;
4631 if (start_decoder(&p)) {
4632 this = vorbis_alloc(&p);
4633 if (this) {
4634 *this = p;
4635 vorbis_pump_first_frame(this);
4636 return this;
4639 if (error) *error = p.error;
4640 vorbis_deinit(&p);
4641 return null;
4645 // s16 samples API
4646 int getFrameShort (int num_c, short** buffer, int num_samples) {
4647 float** output;
4648 int len = getFrameFloat(null, &output);
4649 if (len > num_samples) len = num_samples;
4650 if (len) convert_samples_short(num_c, buffer, 0, vrchannels, output, 0, len);
4651 return len;
4654 int getFrameShortInterleaved (int num_c, short* buffer, int num_shorts) {
4655 float** output;
4656 int len;
4657 if (num_c == 1) return getFrameShort(num_c, &buffer, num_shorts);
4658 len = getFrameFloat(null, &output);
4659 if (len) {
4660 if (len*num_c > num_shorts) len = num_shorts/num_c;
4661 convert_channels_short_interleaved(num_c, buffer, vrchannels, output, 0, len);
4663 return len;
4666 int getSamplesShortInterleaved (int channels, short* buffer, int num_shorts) {
4667 float** outputs;
4668 int len = num_shorts/channels;
4669 int n = 0;
4670 int z = this.vrchannels;
4671 if (z > channels) z = channels;
4672 while (n < len) {
4673 int k = channel_buffer_end-channel_buffer_start;
4674 if (n+k >= len) k = len-n;
4675 if (k) convert_channels_short_interleaved(channels, buffer, vrchannels, channel_buffers.ptr, channel_buffer_start, k);
4676 buffer += k*channels;
4677 n += k;
4678 channel_buffer_start += k;
4679 if (n == len) break;
4680 if (!getFrameFloat(null, &outputs)) break;
4682 return n;
4685 int getSamplesShort (int channels, short** buffer, int len) {
4686 float** outputs;
4687 int n = 0;
4688 int z = this.vrchannels;
4689 if (z > channels) z = channels;
4690 while (n < len) {
4691 int k = channel_buffer_end-channel_buffer_start;
4692 if (n+k >= len) k = len-n;
4693 if (k) convert_samples_short(channels, buffer, n, vrchannels, channel_buffers.ptr, channel_buffer_start, k);
4694 n += k;
4695 channel_buffer_start += k;
4696 if (n == len) break;
4697 if (!getFrameFloat(null, &outputs)) break;
4699 return n;
4703 public int stb_vorbis_decode_filename (string filename, int* channels, int* sample_rate, short** output) {
4704 import core.stdc.stdlib : malloc, realloc;
4706 int data_len, offset, total, limit, error;
4707 short* data;
4708 VorbisDecoder v = stb_vorbis_open_filename(filename, &error, null);
4709 if (v is null) return -1;
4710 limit = v.vrchannels*4096;
4711 *channels = v.vrchannels;
4712 if (sample_rate) *sample_rate = v.sample_rate;
4713 offset = data_len = 0;
4714 total = limit;
4715 data = cast(short*)malloc(total*(*data).sizeof);
4716 if (data is null) {
4717 stb_vorbis_close(v);
4718 return -2;
4720 for (;;) {
4721 int n = stb_vorbis_get_frame_short_interleaved(v, v.vrchannels, data+offset, total-offset);
4722 if (n == 0) break;
4723 data_len += n;
4724 offset += n*v.vrchannels;
4725 if (offset+limit > total) {
4726 short *data2;
4727 total *= 2;
4728 data2 = cast(short*)realloc(data, total*(*data).sizeof);
4729 if (data2 is null) {
4730 import core.stdc.stdlib : free;
4731 free(data);
4732 stb_vorbis_close(v);
4733 return -2;
4735 data = data2;
4738 *output = data;
4739 stb_vorbis_close(v);
4740 return data_len;
4743 public int stb_vorbis_decode_memory (const(void)* mem, int len, int* channels, int* sample_rate, short** output) {
4744 import core.stdc.stdlib : malloc, realloc;
4746 int data_len, offset, total, limit, error;
4747 short* data;
4748 VorbisDecoder v = stb_vorbis_open_memory(mem, len, &error, null);
4749 if (v is null) return -1;
4750 limit = v.vrchannels*4096;
4751 *channels = v.vrchannels;
4752 if (sample_rate) *sample_rate = v.sample_rate;
4753 offset = data_len = 0;
4754 total = limit;
4755 data = cast(short*)malloc(total*(*data).sizeof);
4756 if (data is null) {
4757 stb_vorbis_close(v);
4758 return -2;
4760 for (;;) {
4761 int n = stb_vorbis_get_frame_short_interleaved(v, v.vrchannels, data+offset, total-offset);
4762 if (n == 0) break;
4763 data_len += n;
4764 offset += n*v.vrchannels;
4765 if (offset+limit > total) {
4766 short *data2;
4767 total *= 2;
4768 data2 = cast(short*)realloc(data, total*(*data).sizeof);
4769 if (data2 is null) {
4770 import core.stdc.stdlib : free;
4771 free(data);
4772 stb_vorbis_close(v);
4773 return -2;
4775 data = data2;
4778 *output = data;
4779 stb_vorbis_close(v);
4780 return data_len;
4783 public int stb_vorbis_get_samples_float_interleaved (VorbisDecoder this, int channels, float* buffer, int num_floats) {
4784 float** outputs;
4785 int len = num_floats/channels;
4786 int n = 0;
4787 int z = this.vrchannels;
4788 if (z > channels) z = channels;
4789 while (n < len) {
4790 int k = this.channel_buffer_end-this.channel_buffer_start;
4791 if (n+k >= len) k = len-n;
4792 foreach (immutable j; 0..k) {
4793 foreach (immutable i; 0..z) *buffer++ = (this.channel_buffers.ptr[i])[this.channel_buffer_start+j];
4794 foreach (immutable i; z..channels) *buffer++ = 0;
4796 n += k;
4797 this.channel_buffer_start += k;
4798 if (n == len) break;
4799 if (!stb_vorbis_get_frame_float(this, null, &outputs)) break;
4801 return n;
4805 public int getSamplesFloat (int achans, float** buffer, int num_samples) {
4806 import core.stdc.string : memcpy, memset;
4807 float** outputs;
4808 int n = 0;
4809 int z = vrchannels;
4810 if (z > achans) z = achans;
4811 while (n < num_samples) {
4812 int k = channel_buffer_end-channel_buffer_start;
4813 if (n+k >= num_samples) k = num_samples-n;
4814 if (k) {
4815 foreach (immutable i; 0..z) memcpy(buffer[i]+n, channel_buffers.ptr[i]+channel_buffer_start, float.sizeof*k);
4816 foreach (immutable i; z..achans) memset(buffer[i]+n, 0, float.sizeof*k);
4818 n += k;
4819 channel_buffer_start += k;
4820 if (n == num_samples) break;
4821 if (!getFrameFloat(null, &outputs)) break;
4823 return n;
4826 private: // k8: 'cause i'm evil
4827 private enum cmt_len_size = 2;
4828 nothrow /*@trusted*/ @nogc {
4829 public @property bool comment_empty () const pure { return (comment_get_line_len == 0); }
4831 // 0: error
4832 // includes length itself
4833 private uint comment_get_line_len () const pure {
4834 if (comment_data_pos >= comment_size) return 0;
4835 if (comment_size-comment_data_pos < cmt_len_size) return 0;
4836 uint len = comment_data[comment_data_pos];
4837 len += cast(uint)comment_data[comment_data_pos+1]<<8;
4838 return (len >= cmt_len_size && comment_data_pos+len <= comment_size ? len : 0);
4841 public bool comment_rewind () {
4842 comment_data_pos = 0;
4843 for (;;) {
4844 auto len = comment_get_line_len();
4845 if (!len) { comment_data_pos = comment_size; return false; }
4846 if (len != cmt_len_size) return true;
4847 comment_data_pos += len;
4851 // true: has something to read after skip
4852 public bool comment_skip () {
4853 comment_data_pos += comment_get_line_len();
4854 for (;;) {
4855 auto len = comment_get_line_len();
4856 if (!len) { comment_data_pos = comment_size; return false; }
4857 if (len != cmt_len_size) break;
4858 comment_data_pos += len;
4860 return true;
4863 public const(char)[] comment_line () {
4864 auto len = comment_get_line_len();
4865 if (len < cmt_len_size) return null;
4866 if (len == cmt_len_size) return "";
4867 return (cast(char*)comment_data+comment_data_pos+cmt_len_size)[0..len-cmt_len_size];
4870 public const(char)[] comment_name () {
4871 auto line = comment_line();
4872 if (line.length == 0) return line;
4873 uint epos = 0;
4874 while (epos < line.length && line.ptr[epos] != '=') ++epos;
4875 return (epos < line.length ? line[0..epos] : "");
4878 public const(char)[] comment_value () {
4879 auto line = comment_line();
4880 if (line.length == 0) return line;
4881 uint epos = 0;
4882 while (epos < line.length && line.ptr[epos] != '=') ++epos;
4883 return (epos < line.length ? line[epos+1..$] : line);
4889 // ////////////////////////////////////////////////////////////////////////// //
4890 private:
4891 // cool helper to translate C defines
4892 template cmacroFixVars(T...) {
4894 * 64-bit implementation of fasthash
4896 * Params:
4897 * buf = data buffer
4898 * seed = the seed
4900 * Returns:
4901 * 32-bit or 64-bit hash
4903 usize hashOf (const(void)* buf, usize len, usize seed=0) pure nothrow @trusted @nogc {
4904 enum Get8Bytes = q{
4905 cast(ulong)data[0]|
4906 (cast(ulong)data[1]<<8)|
4907 (cast(ulong)data[2]<<16)|
4908 (cast(ulong)data[3]<<24)|
4909 (cast(ulong)data[4]<<32)|
4910 (cast(ulong)data[5]<<40)|
4911 (cast(ulong)data[6]<<48)|
4912 (cast(ulong)data[7]<<56)
4914 enum m = 0x880355f21e6d1965UL;
4915 auto data = cast(const(ubyte)*)buf;
4916 ulong h = seed;
4917 ulong t;
4918 foreach (immutable _; 0..len/8) {
4919 version(HasUnalignedOps) {
4920 if (__ctfe) {
4921 t = mixin(Get8Bytes);
4922 } else {
4923 t = *cast(ulong*)data;
4925 } else {
4926 t = mixin(Get8Bytes);
4928 data += 8;
4929 t ^= t>>23;
4930 t *= 0x2127599bf4325c37UL;
4931 t ^= t>>47;
4932 h ^= t;
4933 h *= m;
4936 h ^= len*m;
4937 t = 0;
4938 switch (len&7) {
4939 case 7: t ^= cast(ulong)data[6]<<48; goto case 6;
4940 case 6: t ^= cast(ulong)data[5]<<40; goto case 5;
4941 case 5: t ^= cast(ulong)data[4]<<32; goto case 4;
4942 case 4: t ^= cast(ulong)data[3]<<24; goto case 3;
4943 case 3: t ^= cast(ulong)data[2]<<16; goto case 2;
4944 case 2: t ^= cast(ulong)data[1]<<8; goto case 1;
4945 case 1: t ^= cast(ulong)data[0]; goto default;
4946 default:
4947 t ^= t>>23;
4948 t *= 0x2127599bf4325c37UL;
4949 t ^= t>>47;
4950 h ^= t;
4951 h *= m;
4952 break;
4955 h ^= h>>23;
4956 h *= 0x2127599bf4325c37UL;
4957 h ^= h>>47;
4958 static if (usize.sizeof == 4) {
4959 // 32-bit hash
4960 // the following trick converts the 64-bit hashcode to Fermat
4961 // residue, which shall retain information from both the higher
4962 // and lower parts of hashcode.
4963 return cast(usize)(h-(h>>32));
4964 } else {
4965 return h;
4969 string cmacroFixVars (string s, string[] names...) {
4970 assert(T.length == names.length, "cmacroFixVars: names and arguments count mismatch");
4971 enum tmpPfxName = "__temp_prefix__";
4972 string res;
4973 string tmppfx;
4974 uint pos = 0;
4975 // skip empty lines (for pretty printing)
4976 // trim trailing spaces
4977 while (s.length > 0 && s[$-1] <= ' ') s = s[0..$-1];
4978 uint linestpos = 0; // start of the current line
4979 while (pos < s.length) {
4980 if (s[pos] > ' ') break;
4981 if (s[pos] == '\n') linestpos = pos+1;
4982 ++pos;
4984 pos = linestpos;
4985 while (pos+2 < s.length) {
4986 int epos = pos;
4987 while (epos+2 < s.length && (s[epos] != '$' || s[epos+1] != '{')) ++epos;
4988 if (epos > pos) {
4989 if (s.length-epos < 3) break;
4990 res ~= s[pos..epos];
4991 pos = epos;
4993 assert(s[pos] == '$' && s[pos+1] == '{');
4994 pos += 2;
4995 bool found = false;
4996 if (s.length-pos >= tmpPfxName.length+1 && s[pos+tmpPfxName.length] == '}' && s[pos..pos+tmpPfxName.length] == tmpPfxName) {
4997 if (tmppfx.length == 0) {
4998 // generate temporary prefix
4999 auto hash = hashOf(s.ptr, s.length);
5000 immutable char[16] hexChars = "0123456789abcdef";
5001 tmppfx = "_temp_macro_var_";
5002 foreach_reverse (immutable idx; 0..usize.sizeof*2) {
5003 tmppfx ~= hexChars[hash&0x0f];
5004 hash >>= 4;
5006 tmppfx ~= "_";
5008 pos += tmpPfxName.length+1;
5009 res ~= tmppfx;
5010 found = true;
5011 } else {
5012 foreach (immutable nidx, string oname; T) {
5013 static assert(oname.length > 0);
5014 if (s.length-pos >= oname.length+1 && s[pos+oname.length] == '}' && s[pos..pos+oname.length] == oname) {
5015 found = true;
5016 pos += oname.length+1;
5017 res ~= names[nidx];
5018 break;
5022 assert(found, "unknown variable in macro");
5024 if (pos < s.length) res ~= s[pos..$];
5025 return res;
5029 // ////////////////////////////////////////////////////////////////////////// //
5030 /* Version history
5031 1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
5032 1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
5033 avoid discarding last frame of audio data
5034 1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API
5035 some more crash fixes when out of memory or with corrupt files
5036 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
5037 some crash fixes when out of memory or with corrupt files
5038 1.05 - 2015/04/19 - don't define __forceinline if it's redundant
5039 1.04 - 2014/08/27 - fix missing const-correct case in API
5040 1.03 - 2014/08/07 - Warning fixes
5041 1.02 - 2014/07/09 - Declare qsort compare function _cdecl on windows
5042 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float
5043 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in multichannel
5044 (API change) report sample rate for decode-full-file funcs
5045 0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila
5046 0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem
5047 0.99994 - change fast-float-to-int to work in single-precision FPU mode, remove endian-dependence
5048 0.99993 - remove assert that fired on legal files with empty tables
5049 0.99992 - rewind-to-start
5050 0.99991 - bugfix to stb_vorbis_get_samples_short by Bernhard Wodo
5051 0.9999 - (should have been 0.99990) fix no-CRT support, compiling as C++
5052 0.9998 - add a full-decode function with a memory source
5053 0.9997 - fix a bug in the read-from-FILE case in 0.9996 addition
5054 0.9996 - query length of vorbis stream in samples/seconds
5055 0.9995 - bugfix to another optimization that only happened in certain files
5056 0.9994 - bugfix to one of the optimizations that caused significant (but inaudible?) errors
5057 0.9993 - performance improvements; runs in 99% to 104% of time of reference implementation
5058 0.9992 - performance improvement of IMDCT; now performs close to reference implementation
5059 0.9991 - performance improvement of IMDCT
5060 0.999 - (should have been 0.9990) performance improvement of IMDCT
5061 0.998 - no-CRT support from Casey Muratori
5062 0.997 - bugfixes for bugs found by Terje Mathisen
5063 0.996 - bugfix: fast-huffman decode initialized incorrectly for sparse codebooks; fixing gives 10% speedup - found by Terje Mathisen
5064 0.995 - bugfix: fix to 'effective' overrun detection - found by Terje Mathisen
5065 0.994 - bugfix: garbage decode on final VQ symbol of a non-multiple - found by Terje Mathisen
5066 0.993 - bugfix: pushdata API required 1 extra byte for empty page (failed to consume final page if empty) - found by Terje Mathisen
5067 0.992 - fixes for MinGW warning
5068 0.991 - turn fast-float-conversion on by default
5069 0.990 - fix push-mode seek recovery if you seek into the headers
5070 0.98b - fix to bad release of 0.98
5071 0.98 - fix push-mode seek recovery; robustify float-to-int and support non-fast mode
5072 0.97 - builds under c++ (typecasting, don't use 'class' keyword)
5073 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
5074 0.95 - clamping code for 16-bit functions
5075 0.94 - not publically released
5076 0.93 - fixed all-zero-floor case (was decoding garbage)
5077 0.92 - fixed a memory leak
5078 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
5079 0.90 - first public release
5083 ------------------------------------------------------------------------------
5084 This software is available under 2 licenses -- choose whichever you prefer.
5085 ------------------------------------------------------------------------------
5086 ALTERNATIVE A - MIT License
5087 Copyright (c) 2017 Sean Barrett
5088 Permission is hereby granted, free of charge, to any person obtaining a copy of
5089 this software and associated documentation files (the "Software"), to deal in
5090 the Software without restriction, including without limitation the rights to
5091 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5092 of the Software, and to permit persons to whom the Software is furnished to do
5093 so, subject to the following conditions:
5094 The above copyright notice and this permission notice shall be included in all
5095 copies or substantial portions of the Software.
5096 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5097 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5098 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5099 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5100 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5101 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5102 SOFTWARE.
5103 ------------------------------------------------------------------------------
5104 ALTERNATIVE B - Public Domain (www.unlicense.org)
5105 This is free and unencumbered software released into the public domain.
5106 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5107 software, either in source code form or as a compiled binary, for any purpose,
5108 commercial or non-commercial, and by any means.
5109 In jurisdictions that recognize copyright laws, the author or authors of this
5110 software dedicate any and all copyright interest in the software to the public
5111 domain. We make this dedication for the benefit of the public at large and to
5112 the detriment of our heirs and successors. We intend this dedication to be an
5113 overt act of relinquishment in perpetuity of all present and future rights to
5114 this software under copyright law.
5115 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5116 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5117 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5118 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5119 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5120 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5121 ------------------------------------------------------------------------------