Bug Summary

File:Vorbis.c
Warning:line 181, column 3
The left operand of '<<' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple amd64-unknown-openbsd6.8 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Vorbis.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mthread-model posix -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/local/lib/clang/10.0.1 -I /usr/X11R6/include -I /usr/local/include -fdebug-compilation-dir /home/ben/Projects/ClassiCube/src -ferror-limit 19 -fmessage-length 0 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -fobjc-runtime=gnustep -fdiagnostics-show-option -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/ClassiCube/src/scan/2021-01-09-173753-31878-1 -x c Vorbis.c
1#include "Vorbis.h"
2#include "Logger.h"
3#include "Platform.h"
4#include "Event.h"
5#include "ExtMath.h"
6#include "Funcs.h"
7#include "Errors.h"
8#include "Stream.h"
9
10/*########################################################################################################################*
11*-------------------------------------------------------Ogg stream--------------------------------------------------------*
12*#########################################################################################################################*/
13#define OGG_FourCC(a, b, c, d)(((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((
cc_uint32)c << 8) | (cc_uint32)d)
(((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d)
14
15static void Ogg_DiscardPacket(struct OggState* ctx) {
16 ctx->cur += ctx->left;
17 ctx->left = 0;
18}
19
20static void Ogg_NextPacket(struct OggState* ctx) {
21 cc_uint8 part;
22 ctx->left = 0;
23
24 for (; ctx->segmentsRead < ctx->numSegments; ) {
25 part = ctx->segments[ctx->segmentsRead++];
26 ctx->left += part;
27 if (part != 255) break; /* end of this packet */
28 }
29}
30
31static cc_result Ogg_NextPage(struct OggState* ctx) {
32 cc_uint8 header[27];
33 struct Stream* source;
34 cc_uint32 sig, size;
35 cc_result res;
36 int i;
37
38 /* OGG page format:
39 * header[0] (4) page signature
40 * header[4] (1) page version
41 * header[5] (1) page flags
42 * header[6] (8) granule position
43 * header[14] (4) serial number
44 * header[18] (4) page sequence number
45 * header[22] (4) page checksum
46 * header[26] (1) number of segments
47 * [number of segments] number of bytes in each segment
48 * [sum of bytes in each segment] page data
49 */
50 /* An OGG page is then further split into one or more packets */
51 source = ctx->source;
52 if ((res = Stream_Read(source, header, sizeof(header)))) return res;
53
54 sig = Stream_GetU32_BE(&header[0]);
55 if (sig != OGG_FourCC('O','g','g','S')(((cc_uint32)'O' << 24) | ((cc_uint32)'g' << 16) |
((cc_uint32)'g' << 8) | (cc_uint32)'S')
) return OGG_ERR_INVALID_SIG;
56 if (header[4] != 0) return OGG_ERR_VERSION;
57
58 ctx->segmentsRead = 0;
59 ctx->numSegments = header[26];
60 if ((res = Stream_Read(source, ctx->segments, ctx->numSegments))) return res;
61
62 size = 0;
63 for (i = 0; i < ctx->numSegments; i++) size += ctx->segments[i];
64 if ((res = Stream_Read(source, ctx->buffer, size))) return res;
65
66 ctx->cur = ctx->buffer;
67 ctx->last = header[5] & 4;
68 Ogg_NextPacket(ctx);
69 return 0;
70}
71
72static cc_result Ogg_Read(struct OggState* ctx, cc_uint8* data, cc_uint32 count) {
73 cc_uint32 left = count;
74 cc_result res;
75 while (left) {
31
Loop condition is true. Entering loop body
76 if (ctx->left
31.1
Field 'left' is 0
) {
32
Taking false branch
77 count = min(left, ctx->left)((left) < (ctx->left) ? (left) : (ctx->left));
78 Mem_Copy(data, ctx->cur, count);
79
80 ctx->cur += count;
81 ctx->left -= count;
82 left -= count;
83 } else if (ctx->segmentsRead < ctx->numSegments) {
33
Assuming field 'segmentsRead' is >= field 'numSegments'
34
Taking false branch
84 Ogg_NextPacket(ctx);
85 } else {
86 if (ctx->last) return ERR_END_OF_STREAM;
35
Assuming field 'last' is not equal to 0
36
Taking true branch
37
Returning without writing to '*data'
87 if ((res = Ogg_NextPage(ctx))) return res;
88 }
89 }
90 return 0;
91}
92
93static cc_result Ogg_Skip(struct OggState* ctx, cc_uint32 count) {
94 cc_uint8 tmp[3584]; /* not quite 4 KB to avoid chkstk call */
95 cc_uint32 left = count;
96 cc_result res;
97
98 /* TODO: Should Ogg_Read be duplicated here to avoid Mem_Copy call? */
99 /* Probably not worth it considering how small comments are */
100 while (left) {
101 count = min(left, sizeof(tmp))((left) < (sizeof(tmp)) ? (left) : (sizeof(tmp)));
102 if ((res = Ogg_Read(ctx, tmp, count))) return res;
103 left -= count;
104 }
105 return 0;
106}
107
108static cc_result Ogg_ReadU8(struct OggState* ctx, cc_uint8* data) {
109 /* The fast path below almost always gets used */
110 if (!ctx->left) return Ogg_Read(ctx, data, 1);
28
Assuming field 'left' is 0
29
Taking true branch
30
Calling 'Ogg_Read'
38
Returning from 'Ogg_Read'
39
Returning without writing to '*data'
111
112 *data = *ctx->cur;
113 ctx->cur++;
114 ctx->left--;
115 return 0;
116}
117
118static cc_result Ogg_ReadU32(struct OggState* ctx, cc_uint32* value) {
119 cc_uint8 data[4]; cc_result res;
120 if ((res = Ogg_Read(ctx, data, 4))) return res;
121 *value = Stream_GetU32_LE(data); return 0;
122}
123
124void Ogg_Init(struct OggState* ctx, struct Stream* source) {
125 ctx->cur = ctx->buffer;
126 ctx->left = 0;
127 ctx->last = 0;
128 ctx->source = source;
129 ctx->segmentsRead = 0;
130 ctx->numSegments = 0;
131}
132
133
134/*########################################################################################################################*
135*------------------------------------------------------Vorbis utils-------------------------------------------------------*
136*#########################################################################################################################*/
137#define Vorbis_PushByte(ctx, value)ctx->Bits |= (cc_uint32)(value) << ctx->NumBits; ctx
->NumBits += 8;
ctx->Bits |= (cc_uint32)(value) << ctx->NumBits; ctx->NumBits += 8;
138#define Vorbis_PeekBits(ctx, bits)(ctx->Bits & ((1UL << (bits)) - 1UL)) (ctx->Bits & ((1UL << (bits)) - 1UL))
139#define Vorbis_ConsumeBits(ctx, bits)ctx->Bits >>= (bits); ctx->NumBits -= (bits); ctx->Bits >>= (bits); ctx->NumBits -= (bits);
140/* Aligns bit buffer to be on a byte boundary */
141#define Vorbis_AlignBits(ctx)alignSkip = ctx->NumBits & 7; ctx->Bits >>= (
alignSkip); ctx->NumBits -= (alignSkip);;
alignSkip = ctx->NumBits & 7; Vorbis_ConsumeBits(ctx, alignSkip)ctx->Bits >>= (alignSkip); ctx->NumBits -= (alignSkip
);
;
142
143/* TODO: Make sure this is inlined */
144static cc_uint32 Vorbis_ReadBits(struct VorbisState* ctx, cc_uint32 bitsCount) {
145 cc_uint8 portion;
146 cc_uint32 data;
147 cc_result res;
148
149 while (ctx->NumBits < bitsCount) {
12
Assuming 'bitsCount' is <= field 'NumBits'
13
Loop condition is false. Execution continues on line 155
150 res = Ogg_ReadU8(ctx->source, &portion);
151 if (res) { Logger_Abort2(res, "Failed to read byte for vorbis"); }
152 Vorbis_PushByte(ctx, portion)ctx->Bits |= (cc_uint32)(portion) << ctx->NumBits
; ctx->NumBits += 8;
;
153 }
154
155 data = Vorbis_PeekBits(ctx, bitsCount)(ctx->Bits & ((1UL << (bitsCount)) - 1UL)); Vorbis_ConsumeBits(ctx, bitsCount)ctx->Bits >>= (bitsCount); ctx->NumBits -= (bitsCount
);
;
156 return data;
157}
158
159static cc_result Vorbis_TryReadBits(struct VorbisState* ctx, cc_uint32 bitsCount, cc_uint32* data) {
160 cc_uint8 portion;
161 cc_result res;
162
163 while (ctx->NumBits < bitsCount) {
2
Assuming 'bitsCount' is <= field 'NumBits'
3
Loop condition is false. Execution continues on line 169
164 res = Ogg_ReadU8(ctx->source, &portion);
165 if (res) return res;
166 Vorbis_PushByte(ctx, portion)ctx->Bits |= (cc_uint32)(portion) << ctx->NumBits
; ctx->NumBits += 8;
;
167 }
168
169 *data = Vorbis_PeekBits(ctx, bitsCount)(ctx->Bits & ((1UL << (bitsCount)) - 1UL)); Vorbis_ConsumeBits(ctx, bitsCount)ctx->Bits >>= (bitsCount); ctx->NumBits -= (bitsCount
);
;
4
Value assigned to 'packetType', which participates in a condition later
170 return 0;
5
Returning without writing to 'ctx->modeNumBits', which participates in a condition later
6
Returning zero, which participates in a condition later
171}
172
173static cc_uint32 Vorbis_ReadBit(struct VorbisState* ctx) {
174 cc_uint8 portion;
24
'portion' declared without an initial value
175 cc_uint32 data;
176 cc_result res;
177
178 if (!ctx->NumBits) {
25
Assuming field 'NumBits' is 0
26
Taking true branch
179 res = Ogg_ReadU8(ctx->source, &portion);
27
Calling 'Ogg_ReadU8'
40
Returning from 'Ogg_ReadU8'
180 if (res
40.1
'res' is 3437154305
) { Logger_Abort2(res, "Failed to read byte for vorbis"); }
41
Taking true branch
181 Vorbis_PushByte(ctx, portion)ctx->Bits |= (cc_uint32)(portion) << ctx->NumBits
; ctx->NumBits += 8;
;
42
The left operand of '<<' is a garbage value
182 }
183
184 data = Vorbis_PeekBits(ctx, 1)(ctx->Bits & ((1UL << (1)) - 1UL)); Vorbis_ConsumeBits(ctx, 1)ctx->Bits >>= (1); ctx->NumBits -= (1);;
185 return data;
186}
187
188
189static int iLog(int x) {
190 int bits = 0;
191 while (x > 0) { bits++; x >>= 1; }
192 return bits;
193}
194
195static float float32_unpack(struct VorbisState* ctx) {
196 /* ReadBits can't reliably read over 24 bits */
197 cc_uint32 lo = Vorbis_ReadBits(ctx, 16);
198 cc_uint32 hi = Vorbis_ReadBits(ctx, 16);
199 cc_uint32 x = (hi << 16) | lo;
200
201 cc_int32 mantissa = x & 0x1fffff;
202 cc_uint32 exponent = (x & 0x7fe00000) >> 21;
203 if (x & 0x80000000UL) mantissa = -mantissa;
204
205 #define LOG_20.693147180559945 0.693147180559945
206 /* TODO: Can we make this more accurate? maybe ldexp ?? */
207 return (float)(mantissa * Math_Exp(LOG_20.693147180559945 * ((int)exponent - 788))); /* pow(2, x) */
208}
209
210
211/*########################################################################################################################*
212*----------------------------------------------------Vorbis codebooks-----------------------------------------------------*
213*#########################################################################################################################*/
214#define CODEBOOK_SYNC0x564342 0x564342
215struct Codebook {
216 cc_uint32 dimensions, entries, totalCodewords;
217 cc_uint32* codewords;
218 cc_uint32* values;
219 cc_uint32 numCodewords[33]; /* number of codewords of bit length i */
220 /* vector quantisation values */
221 float minValue, deltaValue;
222 cc_uint32 sequenceP, lookupType, lookupValues;
223 cc_uint16* multiplicands;
224};
225
226static void Codebook_Free(struct Codebook* c) {
227 Mem_Free(c->codewords);
228 Mem_Free(c->values);
229 Mem_Free(c->multiplicands);
230}
231
232static cc_uint32 Codebook_Pow(cc_uint32 base, cc_uint32 exp) {
233 cc_uint32 result = 1; /* exponentiation by squaring */
234 while (exp) {
235 if (exp & 1) result *= base;
236 exp >>= 1;
237 base *= base;
238 }
239 return result;
240}
241
242static cc_uint32 Codebook_Lookup1Values(cc_uint32 entries, cc_uint32 dimensions) {
243 cc_uint32 i, pow, next;
244 /* the greatest integer value for which [value] to the power of [dimensions] is less than or equal to [entries] */
245 /* TODO: verify this */
246 for (i = 1; ; i++) {
247 pow = Codebook_Pow(i, dimensions);
248 next = Codebook_Pow(i + 1, dimensions);
249
250 if (next < pow) return i; /* overflow */
251 if (pow == entries) return i;
252 if (next > entries) return i;
253 }
254 return 0;
255}
256
257static cc_bool Codebook_CalcCodewords(struct Codebook* c, cc_uint8* len) {
258 /* This is taken from stb_vorbis.c because I gave up trying */
259 cc_uint32 i, depth;
260 cc_uint32 root, codeword;
261 cc_uint32 next_codewords[33] = { 0 };
262 int offset;
263 int len_offsets[33];
264
265 c->codewords = (cc_uint32*)Mem_Alloc(c->totalCodewords, 4, "codewords");
266 c->values = (cc_uint32*)Mem_Alloc(c->totalCodewords, 4, "values");
267
268 /* Codeword entries are ordered by length */
269 offset = 0;
270 for (i = 0; i < Array_Elems(len_offsets)(sizeof(len_offsets) / sizeof(len_offsets[0])); i++) {
271 len_offsets[i] = offset;
272 offset += c->numCodewords[i];
273 }
274
275 /* add codeword 0 to tree */
276 for (i = 0; i < c->entries; i++) {
277 if (!len[i]) continue;
278 offset = len_offsets[len[i]];
279
280 c->codewords[offset] = 0;
281 c->values[offset] = i;
282
283 len_offsets[len[i]]++;
284 break;
285 }
286
287 /* set codewords that new nodes can start from */
288 for (depth = 1; depth <= len[i]; depth++) {
289 next_codewords[depth] = 1U << (32 - depth);
290 }
291
292 i++; /* first codeword was already handled */
293 for (; i < c->entries; i++) {
294 root = len[i];
295 if (!root) continue;
296 offset = len_offsets[len[i]];
297
298 /* per spec, find lowest possible value (leftmost) */
299 while (root && next_codewords[root] == 0) root--;
300 if (root == 0) return false0;
301
302 codeword = next_codewords[root];
303 next_codewords[root] = 0;
304
305 c->codewords[offset] = codeword;
306 c->values[offset] = i;
307
308 for (depth = len[i]; depth > root; depth--) {
309 next_codewords[depth] = codeword + (1U << (32 - depth));
310 }
311
312 len_offsets[len[i]]++;
313 }
314 return true1;
315}
316
317static cc_result Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook* c) {
318 cc_uint32 sync;
319 cc_uint8* codewordLens;
320 int i, entry;
321 int sparse, len;
322 int runBits, runLen;
323 int valueBits;
324 cc_uint32 lookupValues;
325
326 sync = Vorbis_ReadBits(ctx, 24);
327 if (sync != CODEBOOK_SYNC0x564342) return VORBIS_ERR_CODEBOOK_SYNC;
328 c->dimensions = Vorbis_ReadBits(ctx, 16);
329 c->entries = Vorbis_ReadBits(ctx, 24);
330
331 codewordLens = (cc_uint8*)Mem_Alloc(c->entries, 1, "raw codeword lens");
332 for (i = 0; i < Array_Elems(c->numCodewords)(sizeof(c->numCodewords) / sizeof(c->numCodewords[0])); i++) {
333 c->numCodewords[i] = 0;
334 }
335
336 /* ordered entries flag */
337 if (!Vorbis_ReadBit(ctx)) {
338 sparse = Vorbis_ReadBit(ctx);
339 entry = 0;
340 for (i = 0; i < c->entries; i++) {
341 /* sparse trees may not have all entries */
342 if (sparse && !Vorbis_ReadBit(ctx)){
343 codewordLens[i] = 0;
344 continue; /* unused entry */
345 }
346
347 len = Vorbis_ReadBits(ctx, 5) + 1;
348 codewordLens[i] = len;
349 c->numCodewords[len]++;
350 entry++;
351 }
352 } else {
353 len = Vorbis_ReadBits(ctx, 5) + 1;
354 for (entry = 0; entry < c->entries;) {
355 runBits = iLog(c->entries - entry);
356 runLen = Vorbis_ReadBits(ctx, runBits);
357
358 /* handle corrupted ogg files */
359 if (entry + runLen > c->entries) return VORBIS_ERR_CODEBOOK_ENTRY;
360
361 for (i = 0; i < runLen; i++) { codewordLens[entry++] = len; }
362 c->numCodewords[len++] = runLen;
363 }
364 }
365
366 c->totalCodewords = entry;
367 Codebook_CalcCodewords(c, codewordLens);
368 Mem_Free(codewordLens);
369
370 c->lookupType = Vorbis_ReadBits(ctx, 4);
371 c->multiplicands = NULL((void*)0);
372 if (c->lookupType == 0) return 0;
373 if (c->lookupType > 2) return VORBIS_ERR_CODEBOOK_LOOKUP;
374
375 c->minValue = float32_unpack(ctx);
376 c->deltaValue = float32_unpack(ctx);
377 valueBits = Vorbis_ReadBits(ctx, 4) + 1;
378 c->sequenceP = Vorbis_ReadBit(ctx);
379
380 if (c->lookupType == 1) {
381 lookupValues = Codebook_Lookup1Values(c->entries, c->dimensions);
382 } else {
383 lookupValues = c->entries * c->dimensions;
384 }
385 c->lookupValues = lookupValues;
386
387 c->multiplicands = (cc_uint16*)Mem_Alloc(lookupValues, 2, "multiplicands");
388 for (i = 0; i < lookupValues; i++) {
389 c->multiplicands[i] = Vorbis_ReadBits(ctx, valueBits);
390 }
391 return 0;
392}
393
394static cc_uint32 Codebook_DecodeScalar(struct VorbisState* ctx, struct Codebook* c) {
395 cc_uint32 codeword = 0, shift = 31, depth, i;
396 cc_uint32* codewords = c->codewords;
397 cc_uint32* values = c->values;
398
399 /* TODO: This is so massively slow */
400 for (depth = 1; depth <= 32; depth++, shift--) {
401 codeword |= Vorbis_ReadBit(ctx) << shift;
402
403 for (i = 0; i < c->numCodewords[depth]; i++) {
404 if (codeword != codewords[i]) continue;
405 return values[i];
406 }
407
408 codewords += c->numCodewords[depth];
409 values += c->numCodewords[depth];
410 }
411 Logger_Abort("Invalid huffman code");
412 return -1;
413}
414
415static void Codebook_DecodeVectors(struct VorbisState* ctx, struct Codebook* c, float* v, int step) {
416 cc_uint32 lookupOffset = Codebook_DecodeScalar(ctx, c);
417 float last = 0.0f, value;
418 cc_uint32 i, offset;
419
420 if (c->lookupType == 1) {
421 cc_uint32 indexDivisor = 1;
422 for (i = 0; i < c->dimensions; i++, v += step) {
423 offset = (lookupOffset / indexDivisor) % c->lookupValues;
424 value = c->multiplicands[offset] * c->deltaValue + c->minValue + last;
425
426 *v += value;
427 if (c->sequenceP) last = value;
428 indexDivisor *= c->lookupValues;
429 }
430 } else if (c->lookupType == 2) {
431 offset = lookupOffset * c->dimensions;
432 for (i = 0; i < c->dimensions; i++, offset++, v += step) {
433 value = c->multiplicands[offset] * c->deltaValue + c->minValue + last;
434
435 *v += value;
436 if (c->sequenceP) last = value;
437 }
438 } else {
439 Logger_Abort("Invalid huffman code");
440 }
441}
442
443/*########################################################################################################################*
444*-----------------------------------------------------Vorbis floors-------------------------------------------------------*
445*#########################################################################################################################*/
446#define FLOOR_MAX_PARTITIONS32 32
447#define FLOOR_MAX_CLASSES16 16
448#define FLOOR_MAX_VALUES(32 * 8 + 2) (FLOOR_MAX_PARTITIONS32 * 8 + 2)
449struct Floor {
450 cc_uint8 partitions, multiplier; int range, values;
451 cc_uint8 partitionClasses[FLOOR_MAX_PARTITIONS32];
452 cc_uint8 classDimensions[FLOOR_MAX_CLASSES16];
453 cc_uint8 classSubClasses[FLOOR_MAX_CLASSES16];
454 cc_uint8 classMasterbooks[FLOOR_MAX_CLASSES16];
455 cc_int16 subclassBooks[FLOOR_MAX_CLASSES16][8];
456 cc_int16 xList[FLOOR_MAX_VALUES(32 * 8 + 2)];
457 cc_uint16 listOrder[FLOOR_MAX_VALUES(32 * 8 + 2)];
458 cc_int32 yList[VORBIS_MAX_CHANS8][FLOOR_MAX_VALUES(32 * 8 + 2)];
459};
460
461static const float floor1_inverse_dB_table[256] = {
462 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
463 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f,
464 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f,
465 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f,
466 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f,
467 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f,
468 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f,
469 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f,
470 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f,
471 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f,
472 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f,
473 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f,
474 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f,
475 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f,
476 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f,
477 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f,
478 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f,
479 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f,
480 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f,
481 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f,
482 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f,
483 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f,
484 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f,
485 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f,
486 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f,
487 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f,
488 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f,
489 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f,
490 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f,
491 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f,
492 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f,
493 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, 0.82788260f, 0.88168307f, 0.9389798f, 1.00000000f,
494};
495
496/* TODO: Make this thread safe */
497static cc_int16* tmp_xlist;
498static cc_uint16* tmp_order;
499static void Floor_SortXList(int left, int right) {
500 cc_uint16* values = tmp_order; cc_uint16 value;
501 cc_int16* keys = tmp_xlist; cc_int16 key;
502
503 while (left < right) {
504 int i = left, j = right;
505 cc_int16 pivot = keys[(i + j) >> 1];
506
507 /* partition the list */
508 while (i <= j) {
509 while (pivot > keys[i]) i++;
510 while (pivot < keys[j]) j--;
511 QuickSort_Swap_KV_Maybe()if (i <= j) { key = keys[i]; keys[i] = keys[j]; keys[j] = key
; value = values[i]; values[i] = values[j]; values[j] = value
; i++; j--;}
;
512 }
513 /* recurse into the smaller subset */
514 QuickSort_Recurse(Floor_SortXList)if (j - left <= right - i) { if (left < j) { Floor_SortXList
(left, j); } left = i;} else { if (i < right) { Floor_SortXList
(i, right); } right = j;}
515 }
516}
517
518static cc_result Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
519 static const short ranges[4] = { 256, 128, 84, 64 };
520 int i, j, idx, maxClass;
521 int rangeBits, classNum;
522 cc_int16 xlist_sorted[FLOOR_MAX_VALUES(32 * 8 + 2)];
523
524 f->partitions = Vorbis_ReadBits(ctx, 5);
525 maxClass = -1;
526 for (i = 0; i < f->partitions; i++) {
527 f->partitionClasses[i] = Vorbis_ReadBits(ctx, 4);
528 maxClass = max(maxClass, f->partitionClasses[i])((maxClass) > (f->partitionClasses[i]) ? (maxClass) : (
f->partitionClasses[i]))
;
529 }
530
531 for (i = 0; i <= maxClass; i++) {
532 f->classDimensions[i] = Vorbis_ReadBits(ctx, 3) + 1;
533 f->classSubClasses[i] = Vorbis_ReadBits(ctx, 2);
534
535 if (f->classSubClasses[i]) {
536 f->classMasterbooks[i] = Vorbis_ReadBits(ctx, 8);
537 }
538 for (j = 0; j < (1 << f->classSubClasses[i]); j++) {
539 f->subclassBooks[i][j] = (cc_int16)Vorbis_ReadBits(ctx, 8) - 1;
540 }
541 }
542
543 f->multiplier = Vorbis_ReadBits(ctx, 2) + 1;
544 f->range = ranges[f->multiplier - 1];
545 rangeBits = Vorbis_ReadBits(ctx, 4);
546
547 f->xList[0] = 0;
548 f->xList[1] = 1 << rangeBits;
549 for (i = 0, idx = 2; i < f->partitions; i++) {
550 classNum = f->partitionClasses[i];
551
552 for (j = 0; j < f->classDimensions[classNum]; j++) {
553 f->xList[idx++] = Vorbis_ReadBits(ctx, rangeBits);
554 }
555 }
556 f->values = idx;
557
558 /* sort X list for curve computation later */
559 Mem_Copy(xlist_sorted, f->xList, idx * 2);
560 for (i = 0; i < idx; i++) { f->listOrder[i] = i; }
561
562 tmp_xlist = xlist_sorted;
563 tmp_order = f->listOrder;
564 Floor_SortXList(0, idx - 1);
565 return 0;
566}
567
568static cc_bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, int ch) {
569 cc_int32* yList;
570 int i, j, idx, rangeBits;
571 cc_uint8 klass, cdim, cbits;
572 int bookNum;
573 cc_uint32 csub, cval;
574
575 /* does this frame have any energy */
576 if (!Vorbis_ReadBit(ctx)) return false0;
23
Calling 'Vorbis_ReadBit'
577 yList = f->yList[ch];
578
579 rangeBits = iLog(f->range - 1);
580 yList[0] = Vorbis_ReadBits(ctx, rangeBits);
581 yList[1] = Vorbis_ReadBits(ctx, rangeBits);
582
583 for (i = 0, idx = 2; i < f->partitions; i++) {
584 klass = f->partitionClasses[i];
585 cdim = f->classDimensions[klass];
586 cbits = f->classSubClasses[klass];
587
588 csub = (1 << cbits) - 1;
589 cval = 0;
590 if (cbits) {
591 bookNum = f->classMasterbooks[klass];
592 cval = Codebook_DecodeScalar(ctx, &ctx->codebooks[bookNum]);
593 }
594
595 for (j = 0; j < cdim; j++) {
596 bookNum = f->subclassBooks[klass][cval & csub];
597 cval >>= cbits;
598
599 if (bookNum >= 0) {
600 yList[idx + j] = Codebook_DecodeScalar(ctx, &ctx->codebooks[bookNum]);
601 } else {
602 yList[idx + j] = 0;
603 }
604 }
605 idx += cdim;
606 }
607 return true1;
608}
609
610static int Floor_RenderPoint(int x0, int y0, int x1, int y1, int X) {
611 int dy = y1 - y0, adx = x1 - x0;
612 int ady = Math_AbsI(dy);
613 int err = ady * (X - x0);
614 int off = err / adx;
615
616 if (dy < 0) {
617 return y0 - off;
618 } else {
619 return y0 + off;
620 }
621}
622
623static void Floor_RenderLine(int x0, int y0, int x1, int y1, float* data) {
624 int dy = y1 - y0, adx = x1 - x0;
625 int ady = Math_AbsI(dy);
626 int base = dy / adx, sy;
627 int x = x0, y = y0, err = 0;
628
629 if (dy < 0) {
630 sy = base - 1;
631 } else {
632 sy = base + 1;
633 }
634
635 ady = ady - Math_AbsI(base) * adx;
636 data[x] *= floor1_inverse_dB_table[y];
637
638 for (x = x0 + 1; x < x1; x++) {
639 err = err + ady;
640 if (err >= adx) {
641 err = err - adx;
642 y = y + sy;
643 } else {
644 y = y + base;
645 }
646 data[x] *= floor1_inverse_dB_table[y];
647 }
648}
649
650static int low_neighbor(cc_int16* v, int x) {
651 int n = 0, i, max = Int32_MinValue((cc_int32)-2147483647L - (cc_int32)1L);
652 for (i = 0; i < x; i++) {
653 if (v[i] < v[x] && v[i] > max) { n = i; max = v[i]; }
654 }
655 return n;
656}
657
658static int high_neighbor(cc_int16* v, int x) {
659 int n = 0, i, min = Int32_MaxValue((cc_int32)2147483647L);
660 for (i = 0; i < x; i++) {
661 if (v[i] > v[x] && v[i] < min) { n = i; min = v[i]; }
662 }
663 return n;
664}
665
666static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, int ch) {
667 /* amplitude arrays */
668 cc_int32 YFinal[FLOOR_MAX_VALUES(32 * 8 + 2)];
669 cc_bool Step2[FLOOR_MAX_VALUES(32 * 8 + 2)];
670 cc_int32* yList;
671 float* data;
672 /* amplitude variables */
673 int lo_offset, hi_offset, predicted;
674 int val, highroom, lowroom, room;
675 int i;
676 /* curve variables */
677 int lx, hx, ly, hy;
678 int rawI;
679 float value;
680
681 /* amplitude value synthesis */
682 yList = f->yList[ch];
683 data = ctx->curOutput[ch];
684
685 Step2[0] = true1;
686 Step2[1] = true1;
687 YFinal[0] = yList[0];
688 YFinal[1] = yList[1];
689
690 for (i = 2; i < f->values; i++) {
691 lo_offset = low_neighbor(f->xList, i);
692 hi_offset = high_neighbor(f->xList, i);
693 predicted = Floor_RenderPoint(f->xList[lo_offset], YFinal[lo_offset],
694 f->xList[hi_offset], YFinal[hi_offset], f->xList[i]);
695
696 val = yList[i];
697 highroom = f->range - predicted;
698 lowroom = predicted;
699
700 if (highroom < lowroom) {
701 room = highroom * 2;
702 } else {
703 room = lowroom * 2;
704 }
705
706 if (val) {
707 Step2[lo_offset] = true1;
708 Step2[hi_offset] = true1;
709 Step2[i] = true1;
710
711 if (val >= room) {
712 if (highroom > lowroom) {
713 YFinal[i] = val - lowroom + predicted;
714 } else {
715 YFinal[i] = predicted - val + highroom - 1;
716 }
717 } else {
718 if (val & 1) {
719 YFinal[i] = predicted - (val + 1) / 2;
720 } else {
721 YFinal[i] = predicted + val / 2;
722 }
723 }
724 } else {
725 Step2[i] = false0;
726 YFinal[i] = predicted;
727 }
728 }
729
730 /* curve synthesis */
731 lx = 0; ly = YFinal[f->listOrder[0]] * f->multiplier;
732 hx = 0; hy = ly;
733
734 for (rawI = 1; rawI < f->values; rawI++) {
735 i = f->listOrder[rawI];
736 if (!Step2[i]) continue;
737
738 hx = f->xList[i]; hy = YFinal[i] * f->multiplier;
739 if (lx < hx) {
740 Floor_RenderLine(lx, ly, min(hx, ctx->dataSize)((hx) < (ctx->dataSize) ? (hx) : (ctx->dataSize)), hy, data);
741 }
742 lx = hx; ly = hy;
743 }
744
745 /* fill remainder of floor with a flat line */
746 /* TODO: Is this right? should hy be 0, if Step2 is false for all */
747 if (hx >= ctx->dataSize) return;
748 lx = hx; hx = ctx->dataSize;
749
750 value = floor1_inverse_dB_table[hy];
751 for (; lx < hx; lx++) { data[lx] *= value; }
752}
753
754
755/*########################################################################################################################*
756*----------------------------------------------------Vorbis residues------------------------------------------------------*
757*#########################################################################################################################*/
758#define RESIDUE_MAX_CLASSIFICATIONS65 65
759struct Residue {
760 cc_uint8 type, classifications, classbook;
761 cc_uint32 begin, end, partitionSize;
762 cc_uint8 cascade[RESIDUE_MAX_CLASSIFICATIONS65];
763 cc_int16 books[RESIDUE_MAX_CLASSIFICATIONS65][8];
764};
765
766static cc_result Residue_DecodeSetup(struct VorbisState* ctx, struct Residue* r, int type) {
767 cc_int16 codebook;
768 int i, j;
769
770 r->type = (cc_uint8)type;
771 r->begin = Vorbis_ReadBits(ctx, 24);
772 r->end = Vorbis_ReadBits(ctx, 24);
773 r->partitionSize = Vorbis_ReadBits(ctx, 24) + 1;
774 r->classifications = Vorbis_ReadBits(ctx, 6) + 1;
775 r->classbook = Vorbis_ReadBits(ctx, 8);
776
777 for (i = 0; i < r->classifications; i++) {
778 r->cascade[i] = Vorbis_ReadBits(ctx, 3);
779 if (!Vorbis_ReadBit(ctx)) continue;
780 r->cascade[i] |= Vorbis_ReadBits(ctx, 5) << 3;
781 }
782
783 for (i = 0; i < r->classifications; i++) {
784 for (j = 0; j < 8; j++) {
785 codebook = -1;
786
787 if (r->cascade[i] & (1 << j)) {
788 codebook = Vorbis_ReadBits(ctx, 8);
789 }
790 r->books[i][j] = codebook;
791 }
792 }
793 return 0;
794}
795
796static void Residue_DecodeCore(struct VorbisState* ctx, struct Residue* r, cc_uint32 size, int ch, cc_bool* doNotDecode, float** data) {
797 struct Codebook* classbook;
798 cc_uint32 residueBeg, residueEnd;
799 cc_uint32 classwordsPerCodeword;
800 cc_uint32 nToRead, partitionsToRead;
801 int pass, i, j, k;
802
803 /* classification variables */
804 cc_uint8* classifications[VORBIS_MAX_CHANS8];
805 cc_uint8* classifications_raw;
806 cc_uint32 temp;
807
808 /* partition variables */
809 struct Codebook* c;
810 float* v;
811 cc_uint32 offset;
812 cc_uint8 klass;
813 cc_int16 book;
814
815 /* per spec, ensure decoded bounds are actually in size */
816 residueBeg = min(r->begin, size)((r->begin) < (size) ? (r->begin) : (size));
817 residueEnd = min(r->end, size)((r->end) < (size) ? (r->end) : (size));
818 classbook = &ctx->codebooks[r->classbook];
819
820 classwordsPerCodeword = classbook->dimensions;
821 nToRead = residueEnd - residueBeg;
822 partitionsToRead = nToRead / r->partitionSize;
823
824 /* first half of temp array is used by residue type 2 for storing temp interleaved data */
825 classifications_raw = ((cc_uint8*)ctx->temp) + (ctx->dataSize * ctx->channels * 5);
826 for (i = 0; i < ch; i++) {
827 /* add a bit of space in case classwordsPerCodeword is > partitionsToRead*/
828 classifications[i] = classifications_raw + i * (partitionsToRead + 64);
829 }
830
831 if (nToRead == 0) return;
832 for (pass = 0; pass < 8; pass++) {
833 cc_uint32 partitionCount = 0;
834 while (partitionCount < partitionsToRead) {
835
836 /* read classifications in pass 0 */
837 if (pass == 0) {
838 for (j = 0; j < ch; j++) {
839 if (doNotDecode[j]) continue;
840
841 temp = Codebook_DecodeScalar(ctx, classbook);
842 for (i = classwordsPerCodeword - 1; i >= 0; i--) {
843 classifications[j][i + partitionCount] = temp % r->classifications;
844 temp /= r->classifications;
845 }
846 }
847 }
848
849 for (i = 0; i < classwordsPerCodeword && partitionCount < partitionsToRead; i++) {
850 for (j = 0; j < ch; j++) {
851 if (doNotDecode[j]) continue;
852
853 klass = classifications[j][partitionCount];
854 book = r->books[klass][pass];
855 if (book < 0) continue;
856
857 offset = residueBeg + partitionCount * r->partitionSize;
858 v = data[j] + offset;
859 c = &ctx->codebooks[book];
860
861 if (r->type == 0) {
862 int step = r->partitionSize / c->dimensions;
863 for (k = 0; k < step; k++) {
864 Codebook_DecodeVectors(ctx, c, v, step); v++;
865 }
866 } else {
867 for (k = 0; k < r->partitionSize; k += c->dimensions) {
868 Codebook_DecodeVectors(ctx, c, v, 1); v += c->dimensions;
869 }
870 }
871 }
872 partitionCount++;
873 }
874 }
875 }
876}
877
878static void Residue_DecodeFrame(struct VorbisState* ctx, struct Residue* r, int ch, cc_bool* doNotDecode, float** data) {
879 cc_uint32 size = ctx->dataSize;
880 float* interleaved;
881 cc_bool decodeAny;
882 int i, j;
883
884 if (r->type == 2) {
885 decodeAny = false0;
886
887 /* type 2 decodes all channel vectors, if at least 1 channel to decode */
888 for (i = 0; i < ch; i++) {
889 if (!doNotDecode[i]) decodeAny = true1;
890 }
891 if (!decodeAny) return;
892 decodeAny = false0; /* because DecodeCore expects this to be 'false' for 'do not decode' */
893
894 interleaved = ctx->temp;
895 /* TODO: avoid using ctx->temp and deinterleaving at all */
896 /* TODO: avoid setting memory to 0 here */
897 Mem_Set(interleaved, 0, ctx->dataSize * ctx->channels * sizeof(float));
898 Residue_DecodeCore(ctx, r, size * ch, 1, &decodeAny, &interleaved);
899
900 /* deinterleave type 2 output */
901 for (i = 0; i < size; i++) {
902 for (j = 0; j < ch; j++) {
903 data[j][i] = interleaved[i * ch + j];
904 }
905 }
906 } else {
907 Residue_DecodeCore(ctx, r, size, ch, doNotDecode, data);
908 }
909}
910
911
912/*########################################################################################################################*
913*----------------------------------------------------Vorbis mappings------------------------------------------------------*
914*#########################################################################################################################*/
915#define MAPPING_MAX_COUPLINGS256 256
916#define MAPPING_MAX_SUBMAPS15 15
917struct Mapping {
918 cc_uint8 couplingSteps, submaps;
919 cc_uint8 mux[VORBIS_MAX_CHANS8];
920 cc_uint8 floorIdx[MAPPING_MAX_SUBMAPS15];
921 cc_uint8 residueIdx[MAPPING_MAX_SUBMAPS15];
922 cc_uint8 magnitude[MAPPING_MAX_COUPLINGS256];
923 cc_uint8 angle[MAPPING_MAX_COUPLINGS256];
924};
925
926static cc_result Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m) {
927 int i, submaps, reserved;
928 int couplingSteps, couplingBits;
929
930 submaps = 1;
931 if (Vorbis_ReadBit(ctx)) {
932 submaps = Vorbis_ReadBits(ctx, 4) + 1;
933 }
934
935 couplingSteps = 0;
936 if (Vorbis_ReadBit(ctx)) {
937 couplingSteps = Vorbis_ReadBits(ctx, 8) + 1;
938 /* TODO: How big can couplingSteps ever really get in practice? */
939 couplingBits = iLog(ctx->channels - 1);
940
941 for (i = 0; i < couplingSteps; i++) {
942 m->magnitude[i] = Vorbis_ReadBits(ctx, couplingBits);
943 m->angle[i] = Vorbis_ReadBits(ctx, couplingBits);
944 if (m->magnitude[i] == m->angle[i]) return VORBIS_ERR_MAPPING_CHANS;
945 }
946 }
947
948 reserved = Vorbis_ReadBits(ctx, 2);
949 if (reserved != 0) return VORBIS_ERR_MAPPING_RESERVED;
950 m->submaps = submaps;
951 m->couplingSteps = couplingSteps;
952
953 if (submaps > 1) {
954 for (i = 0; i < ctx->channels; i++) {
955 m->mux[i] = Vorbis_ReadBits(ctx, 4);
956 }
957 } else {
958 for (i = 0; i < ctx->channels; i++) {
959 m->mux[i] = 0;
960 }
961 }
962
963 for (i = 0; i < submaps; i++) {
964 Vorbis_ReadBits(ctx, 8); /* time value */
965 m->floorIdx[i] = Vorbis_ReadBits(ctx, 8);
966 m->residueIdx[i] = Vorbis_ReadBits(ctx, 8);
967 }
968 return 0;
969}
970
971
972/*########################################################################################################################*
973*------------------------------------------------------imdct impl---------------------------------------------------------*
974*#########################################################################################################################*/
975#define PI3.1415926535897931f MATH_PI3.1415926535897931f
976void imdct_slow(float* in, float* out, int N) {
977 double sum;
978 int i, k;
979
980 for (i = 0; i < 2 * N; i++) {
981 sum = 0;
982 for (k = 0; k < N; k++) {
983 sum += in[k] * Math_Cos((PI3.1415926535897931f / N) * (i + 0.5 + N * 0.5) * (k + 0.5));
984 }
985 out[i] = sum;
986 }
987}
988
989static cc_uint32 Vorbis_ReverseBits(cc_uint32 v) {
990 v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
991 v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
992 v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
993 v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
994 v = (v >> 16) | (v << 16);
995 return v;
996}
997
998void imdct_init(struct imdct_state* state, int n) {
999 int k, k2, n4 = n >> 2, n8 = n >> 3, log2_n;
1000 float *A = state->a, *B = state->b, *C = state->c;
1001 cc_uint32* reversed;
1002
1003 log2_n = Math_Log2(n);
1004 reversed = state->reversed;
1005 state->n = n; state->log2_n = log2_n;
1006
1007 /* setup twiddle factors */
1008 for (k = 0, k2 = 0; k < n4; k++, k2 += 2) {
1009 A[k2] = (float)Math_Cos((4*k * PI3.1415926535897931f) / n);
1010 A[k2+1] = -(float)Math_Sin((4*k * PI3.1415926535897931f) / n);
1011 B[k2] = (float)Math_Cos(((k2+1) * PI3.1415926535897931f) / (2*n));
1012 B[k2+1] = (float)Math_Sin(((k2+1) * PI3.1415926535897931f) / (2*n));
1013 }
1014 for (k = 0, k2 = 0; k < n8; k++, k2 += 2) {
1015 C[k2] = (float)Math_Cos(((k2+1) * (2*PI3.1415926535897931f)) / n);
1016 C[k2+1] = -(float)Math_Sin(((k2+1) * (2*PI3.1415926535897931f)) / n);
1017 }
1018
1019 for (k = 0; k < n8; k++) {
1020 reversed[k] = Vorbis_ReverseBits(k) >> (32-log2_n+3);
1021 }
1022}
1023
1024void imdct_calc(float* in, float* out, struct imdct_state* state) {
1025 int k, k2, k4, k8, n = state->n;
1026 int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, n3_4 = n - n4;
1027 int l, log2_n;
1028 cc_uint32* reversed;
1029
1030 /* Optimised algorithm from "The use of multirate filter banks for coding of high quality digital audio" */
1031 /* Uses a few fixes for the paper noted at http://www.nothings.org/stb_vorbis/mdct_01.txt */
1032 float *A = state->a, *B = state->b, *C = state->c;
1033
1034 float u[VORBIS_MAX_BLOCK_SIZE8192];
1035 float w[VORBIS_MAX_BLOCK_SIZE8192];
1036 float e_1, e_2, f_1, f_2;
1037 float g_1, g_2, h_1, h_2;
1038 float x_1, x_2, y_1, y_2;
1039
1040 /* spectral coefficients, step 1, step 2 */
1041 for (k = 0, k2 = 0, k4 = 0; k < n8; k++, k2 += 2, k4 += 4) {
1042 e_1 = -in[k4+3]; e_2 = -in[k4+1];
1043 g_1 = e_1 * A[n2-1-k2] + e_2 * A[n2-2-k2];
1044 g_2 = e_1 * A[n2-2-k2] - e_2 * A[n2-1-k2];
1045
1046 f_1 = in[n2-4-k4]; f_2 = in[n2-2-k4];
1047 h_2 = f_1 * A[n4-2-k2] - f_2 * A[n4-1-k2];
1048 h_1 = f_1 * A[n4-1-k2] + f_2 * A[n4-2-k2];
1049
1050 w[n2+3+k4] = h_2 + g_2;
1051 w[n2+1+k4] = h_1 + g_1;
1052
1053 w[k4+3] = (h_2 - g_2) * A[n2-4-k4] - (h_1 - g_1) * A[n2-3-k4];
1054 w[k4+1] = (h_1 - g_1) * A[n2-4-k4] + (h_2 - g_2) * A[n2-3-k4];
1055 }
1056
1057 /* step 3 */
1058 log2_n = state->log2_n;
1059 for (l = 0; l <= log2_n - 4; l++) {
1060 int k0 = n >> (l+2), k1 = 1 << (l+3);
1061 int r, r4, rMax = n >> (l+4), s2, s2Max = 1 << (l+2);
1062
1063 for (r = 0, r4 = 0; r < rMax; r++, r4 += 4) {
1064 for (s2 = 0; s2 < s2Max; s2 += 2) {
1065 e_1 = w[n-1-k0*s2-r4]; e_2 = w[n-3-k0*s2-r4];
1066 f_1 = w[n-1-k0*(s2+1)-r4]; f_2 = w[n-3-k0*(s2+1)-r4];
1067
1068 u[n-1-k0*s2-r4] = e_1 + f_1;
1069 u[n-3-k0*s2-r4] = e_2 + f_2;
1070
1071 u[n-1-k0*(s2+1)-r4] = (e_1 - f_1) * A[r*k1] - (e_2 - f_2) * A[r*k1+1];
1072 u[n-3-k0*(s2+1)-r4] = (e_2 - f_2) * A[r*k1] + (e_1 - f_1) * A[r*k1+1];
1073 }
1074 }
1075
1076 /* TODO: eliminate this, do w/u in-place */
1077 /* TODO: dynamically allocate mem for imdct */
1078 if (l+1 <= log2_n - 4) {
1079 Mem_Copy(w, u, sizeof(u));
1080 }
1081 }
1082
1083 /* step 4, step 5, step 6, step 7, step 8, output */
1084 reversed = state->reversed;
1085 for (k = 0, k2 = 0, k8 = 0; k < n8; k++, k2 += 2, k8 += 8) {
1086 cc_uint32 j = reversed[k], j8 = j << 3;
1087 e_1 = u[n-j8-1]; e_2 = u[n-j8-3];
1088 f_1 = u[j8+3]; f_2 = u[j8+1];
1089
1090 g_1 = e_1 + f_1 + C[k2+1] * (e_1 - f_1) + C[k2] * (e_2 + f_2);
1091 h_1 = e_1 + f_1 - C[k2+1] * (e_1 - f_1) - C[k2] * (e_2 + f_2);
1092 g_2 = e_2 - f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
1093 h_2 = -e_2 + f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
1094
1095 x_1 = -0.5f * (g_1 * B[k2] + g_2 * B[k2+1]);
1096 x_2 = -0.5f * (g_1 * B[k2+1] - g_2 * B[k2]);
1097 out[n4-1-k] = -x_2;
1098 out[n4+k] = x_2;
1099 out[n3_4-1-k] = x_1;
1100 out[n3_4+k] = x_1;
1101
1102 y_1 = -0.5f * (h_1 * B[n2-2-k2] + h_2 * B[n2-1-k2]);
1103 y_2 = -0.5f * (h_1 * B[n2-1-k2] - h_2 * B[n2-2-k2]);
1104 out[k] = -y_2;
1105 out[n2-1-k] = y_2;
1106 out[n2+k] = y_1;
1107 out[n-1-k] = y_1;
1108 }
1109}
1110
1111
1112/*########################################################################################################################*
1113*-----------------------------------------------------Vorbis setup--------------------------------------------------------*
1114*#########################################################################################################################*/
1115struct Mode { cc_uint8 blockSizeFlag, mappingIdx; };
1116static cc_result Mode_DecodeSetup(struct VorbisState* ctx, struct Mode* m) {
1117 int windowType, transformType;
1118 m->blockSizeFlag = Vorbis_ReadBit(ctx);
1119
1120 windowType = Vorbis_ReadBits(ctx, 16);
1121 if (windowType != 0) return VORBIS_ERR_MODE_WINDOW;
1122 transformType = Vorbis_ReadBits(ctx, 16);
1123 if (transformType != 0) return VORBIS_ERR_MODE_TRANSFORM;
1124
1125 m->mappingIdx = Vorbis_ReadBits(ctx, 8);
1126 return 0;
1127}
1128
1129static void Vorbis_CalcWindow(struct VorbisWindow* window, int blockSize) {
1130 int i, n = blockSize / 2;
1131 float *cur_window, *prev_window;
1132 double inner;
1133
1134 window->Cur = window->Prev + n;
1135 cur_window = window->Cur;
1136 prev_window = window->Prev;
1137
1138 for (i = 0; i < n; i++) {
1139 inner = Math_Sin((i + 0.5) / n * (PI3.1415926535897931f/2));
1140 cur_window[i] = Math_Sin((PI3.1415926535897931f/2) * inner * inner);
1141 }
1142 for (i = 0; i < n; i++) {
1143 inner = Math_Sin((i + 0.5) / n * (PI3.1415926535897931f/2) + (PI3.1415926535897931f/2));
1144 prev_window[i] = Math_Sin((PI3.1415926535897931f/2) * inner * inner);
1145 }
1146}
1147
1148void Vorbis_Free(struct VorbisState* ctx) {
1149 int i;
1150 for (i = 0; i < ctx->numCodebooks; i++) {
1151 Codebook_Free(&ctx->codebooks[i]);
1152 }
1153
1154 Mem_Free(ctx->codebooks);
1155 Mem_Free(ctx->floors);
1156 Mem_Free(ctx->residues);
1157 Mem_Free(ctx->mappings);
1158 Mem_Free(ctx->modes);
1159 Mem_Free(ctx->windowRaw);
1160 Mem_Free(ctx->temp);
1161}
1162
1163static cc_bool Vorbis_ValidBlockSize(cc_uint32 size) {
1164 return size >= 64 && size <= VORBIS_MAX_BLOCK_SIZE8192 && Math_IsPowOf2(size);
1165}
1166
1167static cc_result Vorbis_CheckHeader(struct VorbisState* ctx, cc_uint8 type) {
1168 cc_uint8 header[7];
1169 cc_bool OK;
1170 cc_result res;
1171
1172 if ((res = Ogg_Read(ctx->source, header, sizeof(header)))) return res;
1173 if (header[0] != type) return VORBIS_ERR_WRONG_HEADER;
1174
1175 OK =
1176 header[1] == 'v' && header[2] == 'o' && header[3] == 'r' &&
1177 header[4] == 'b' && header[5] == 'i' && header[6] == 's';
1178 return OK ? 0 : ERR_INVALID_ARGUMENT;
1179}
1180
1181static cc_result Vorbis_DecodeIdentifier(struct VorbisState* ctx) {
1182 cc_uint8 header[23];
1183 cc_uint32 version;
1184 cc_result res;
1185
1186 if ((res = Ogg_Read(ctx->source, header, sizeof(header)))) return res;
1187 version = Stream_GetU32_LE(&header[0]);
1188 if (version != 0) return VORBIS_ERR_VERSION;
1189
1190 ctx->channels = header[4];
1191 ctx->sampleRate = Stream_GetU32_LE(&header[5]);
1192 /* (12) bitrate_maximum, nominal, minimum */
1193 ctx->blockSizes[0] = 1 << (header[21] & 0xF);
1194 ctx->blockSizes[1] = 1 << (header[21] >> 4);
1195
1196 if (!Vorbis_ValidBlockSize(ctx->blockSizes[0])) return VORBIS_ERR_BLOCKSIZE;
1197 if (!Vorbis_ValidBlockSize(ctx->blockSizes[1])) return VORBIS_ERR_BLOCKSIZE;
1198 if (ctx->blockSizes[0] > ctx->blockSizes[1]) return VORBIS_ERR_BLOCKSIZE;
1199
1200 if (ctx->channels == 0 || ctx->channels > VORBIS_MAX_CHANS8) return VORBIS_ERR_CHANS;
1201 /* check framing flag */
1202 return (header[22] & 1) ? 0 : VORBIS_ERR_FRAMING;
1203}
1204
1205static cc_result Vorbis_DecodeComments(struct VorbisState* ctx) {
1206 cc_uint32 i, len, comments;
1207 cc_uint8 flag;
1208 cc_result res;
1209 struct OggState* source = ctx->source;
1210
1211 /* vendor name, followed by comments */
1212 if ((res = Ogg_ReadU32(source, &len))) return res;
1213 if ((res = Ogg_Skip(source, len))) return res;
1214 if ((res = Ogg_ReadU32(source, &comments))) return res;
1215
1216 for (i = 0; i < comments; i++) {
1217 /* comments such as artist, year, etc */
1218 if ((res = Ogg_ReadU32(source, &len))) return res;
1219 if ((res = Ogg_Skip(source, len))) return res;
1220 }
1221
1222 /* check framing flag */
1223 if ((res = Ogg_ReadU8(source, &flag))) return res;
1224 return (flag & 1) ? 0 : VORBIS_ERR_FRAMING;
1225}
1226
1227static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
1228 cc_uint32 framing, alignSkip;
1229 int i, count;
1230 cc_result res;
1231
1232 count = Vorbis_ReadBits(ctx, 8) + 1;
1233 ctx->codebooks = (struct Codebook*)Mem_TryAlloc(count, sizeof(struct Codebook));
1234 if (!ctx->codebooks) return ERR_OUT_OF_MEMORY;
1235
1236 for (i = 0; i < count; i++) {
1237 res = Codebook_DecodeSetup(ctx, &ctx->codebooks[i]);
1238 if (res) return res;
1239 }
1240 ctx->numCodebooks = count;
1241
1242 count = Vorbis_ReadBits(ctx, 6) + 1;
1243 for (i = 0; i < count; i++) {
1244 int time = Vorbis_ReadBits(ctx, 16);
1245 if (time != 0) return VORBIS_ERR_TIME_TYPE;
1246 }
1247
1248 count = Vorbis_ReadBits(ctx, 6) + 1;
1249 ctx->floors = (struct Floor*)Mem_TryAlloc(count, sizeof(struct Floor));
1250 if (!ctx->floors) return ERR_OUT_OF_MEMORY;
1251
1252 for (i = 0; i < count; i++) {
1253 int floor = Vorbis_ReadBits(ctx, 16);
1254 if (floor != 1) return VORBIS_ERR_FLOOR_TYPE;
1255
1256 res = Floor_DecodeSetup(ctx, &ctx->floors[i]);
1257 if (res) return res;
1258 }
1259
1260 count = Vorbis_ReadBits(ctx, 6) + 1;
1261 ctx->residues = (struct Residue*)Mem_TryAlloc(count, sizeof(struct Residue));
1262 if (!ctx->residues) return ERR_OUT_OF_MEMORY;
1263
1264 for (i = 0; i < count; i++) {
1265 int residue = Vorbis_ReadBits(ctx, 16);
1266 if (residue > 2) return VORBIS_ERR_FLOOR_TYPE;
1267
1268 res = Residue_DecodeSetup(ctx, &ctx->residues[i], residue);
1269 if (res) return res;
1270 }
1271
1272 count = Vorbis_ReadBits(ctx, 6) + 1;
1273 ctx->mappings = (struct Mapping*)Mem_TryAlloc(count, sizeof(struct Mapping));
1274 if (!ctx->mappings) return ERR_OUT_OF_MEMORY;
1275
1276 for (i = 0; i < count; i++) {
1277 int mapping = Vorbis_ReadBits(ctx, 16);
1278 if (mapping != 0) return VORBIS_ERR_MAPPING_TYPE;
1279
1280 res = Mapping_DecodeSetup(ctx, &ctx->mappings[i]);
1281 if (res) return res;
1282 }
1283
1284 count = Vorbis_ReadBits(ctx, 6) + 1;
1285 ctx->modes = (struct Mode*)Mem_TryAlloc(count, sizeof(struct Mode));
1286 if (!ctx->modes) return ERR_OUT_OF_MEMORY;
1287
1288 for (i = 0; i < count; i++) {
1289 res = Mode_DecodeSetup(ctx, &ctx->modes[i]);
1290 if (res) return res;
1291 }
1292
1293 ctx->modeNumBits = iLog(count - 1); /* ilog([vorbis_mode_count]-1) bits */
1294 framing = Vorbis_ReadBit(ctx);
1295 Vorbis_AlignBits(ctx)alignSkip = ctx->NumBits & 7; ctx->Bits >>= (
alignSkip); ctx->NumBits -= (alignSkip);;
;
1296 /* check framing flag */
1297 return (framing & 1) ? 0 : VORBIS_ERR_FRAMING;
1298}
1299
1300cc_result Vorbis_DecodeHeaders(struct VorbisState* ctx) {
1301 cc_uint32 count;
1302 cc_result res;
1303
1304 if ((res = Vorbis_CheckHeader(ctx, 1))) return res;
1305 if ((res = Vorbis_DecodeIdentifier(ctx))) return res;
1306 Ogg_DiscardPacket(ctx->source);
1307
1308 if ((res = Vorbis_CheckHeader(ctx, 3))) return res;
1309 if ((res = Vorbis_DecodeComments(ctx))) return res;
1310 Ogg_DiscardPacket(ctx->source);
1311
1312 if ((res = Vorbis_CheckHeader(ctx, 5))) return res;
1313 if ((res = Vorbis_DecodeSetup(ctx))) return res;
1314 Ogg_DiscardPacket(ctx->source);
1315
1316 /* window calculations can be pre-computed here */
1317 count = ctx->blockSizes[0] + ctx->blockSizes[1];
1318 ctx->windowRaw = (float*)Mem_TryAlloc(count, sizeof(float));
1319 if (!ctx->windowRaw) return ERR_OUT_OF_MEMORY;
1320
1321 ctx->windows[0].Prev = ctx->windowRaw;
1322 ctx->windows[1].Prev = ctx->windowRaw + ctx->blockSizes[0];
1323
1324 Vorbis_CalcWindow(&ctx->windows[0], ctx->blockSizes[0]);
1325 Vorbis_CalcWindow(&ctx->windows[1], ctx->blockSizes[1]);
1326
1327 count = ctx->channels * ctx->blockSizes[1];
1328 ctx->temp = (float*)Mem_TryAllocCleared(count * 3, sizeof(float));
1329 if (!ctx->temp) return ERR_OUT_OF_MEMORY;
1330
1331 ctx->values[0] = ctx->temp + count;
1332 ctx->values[1] = ctx->temp + count * 2;
1333
1334 imdct_init(&ctx->imdct[0], ctx->blockSizes[0]);
1335 imdct_init(&ctx->imdct[1], ctx->blockSizes[1]);
1336 return 0;
1337}
1338
1339
1340/*########################################################################################################################*
1341*-----------------------------------------------------Vorbis frame--------------------------------------------------------*
1342*#########################################################################################################################*/
1343cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
1344 /* frame header */
1345 cc_uint32 packetType;
1346 struct Mapping* mapping;
1347 struct Mode* mode;
1348 int modeIdx;
1349
1350 /* floor/residue */
1351 cc_bool hasFloor[VORBIS_MAX_CHANS8];
1352 cc_bool hasResidue[VORBIS_MAX_CHANS8];
1353 cc_bool doNotDecode[VORBIS_MAX_CHANS8];
1354 float* data[VORBIS_MAX_CHANS8];
1355 int submap, floorIdx;
1356 int ch, residueIdx;
1357
1358 /* inverse coupling */
1359 int magChannel, angChannel;
1360 float* magValues, m;
1361 float* angValues, a;
1362
1363 /* misc variables */
1364 float* tmp;
1365 cc_uint32 alignSkip;
1366 int i, j;
1367 cc_result res;
1368
1369 res = Vorbis_TryReadBits(ctx, 1, &packetType);
1
Calling 'Vorbis_TryReadBits'
7
Returning from 'Vorbis_TryReadBits'
1370 if (res
7.1
'res' is 0
) return res;
8
Taking false branch
1371 if (packetType) return VORBIS_ERR_FRAME_TYPE;
9
Assuming 'packetType' is 0
10
Taking false branch
1372
1373 modeIdx = Vorbis_ReadBits(ctx, ctx->modeNumBits);
11
Calling 'Vorbis_ReadBits'
14
Returning from 'Vorbis_ReadBits'
1374 mode = &ctx->modes[modeIdx];
1375 mapping = &ctx->mappings[mode->mappingIdx];
1376
1377 /* decode window shape */
1378 ctx->curBlockSize = ctx->blockSizes[mode->blockSizeFlag];
1379 ctx->dataSize = ctx->curBlockSize / 2;
1380 /* long window lapping flags - we don't care about them though */
1381 if (mode->blockSizeFlag) { Vorbis_ReadBits(ctx, 2); } /* TODO: do we just SkipBits here */
15
Assuming field 'blockSizeFlag' is 0
16
Taking false branch
1382
1383 /* swap prev and cur outputs around */
1384 tmp = ctx->values[1]; ctx->values[1] = ctx->values[0]; ctx->values[0] = tmp;
1385 Mem_Set(ctx->values[0], 0, ctx->channels * ctx->curBlockSize);
1386
1387 for (i = 0; i < ctx->channels; i++) {
17
Assuming 'i' is < field 'channels'
18
Loop condition is true. Entering loop body
19
Assuming 'i' is >= field 'channels'
20
Loop condition is false. Execution continues on line 1393
1388 ctx->curOutput[i] = ctx->values[0] + i * ctx->curBlockSize;
1389 ctx->prevOutput[i] = ctx->values[1] + i * ctx->prevBlockSize;
1390 }
1391
1392 /* decode floor */
1393 for (i = 0; i < ctx->channels; i++) {
21
Loop condition is true. Entering loop body
1394 submap = mapping->mux[i];
1395 floorIdx = mapping->floorIdx[submap];
1396 hasFloor[i] = Floor_DecodeFrame(ctx, &ctx->floors[floorIdx], i);
22
Calling 'Floor_DecodeFrame'
1397 hasResidue[i] = hasFloor[i];
1398 }
1399
1400 /* non-zero vector propogate */
1401 for (i = 0; i < mapping->couplingSteps; i++) {
1402 magChannel = mapping->magnitude[i];
1403 angChannel = mapping->angle[i];
1404
1405 if (hasResidue[magChannel] || hasResidue[angChannel]) {
1406 hasResidue[magChannel] = true1; hasResidue[angChannel] = true1;
1407 }
1408 }
1409
1410 /* decode residue */
1411 for (i = 0; i < mapping->submaps; i++) {
1412 ch = 0;
1413 /* map residue data to actual channel data */
1414 for (j = 0; j < ctx->channels; j++) {
1415 if (mapping->mux[j] != i) continue;
1416
1417 doNotDecode[ch] = !hasResidue[j];
1418 data[ch] = ctx->curOutput[j];
1419 ch++;
1420 }
1421
1422 residueIdx = mapping->floorIdx[i];
1423 Residue_DecodeFrame(ctx, &ctx->residues[residueIdx], ch, doNotDecode, data);
1424 }
1425
1426 /* inverse coupling */
1427 for (i = mapping->couplingSteps - 1; i >= 0; i--) {
1428 magValues = ctx->curOutput[mapping->magnitude[i]];
1429 angValues = ctx->curOutput[mapping->angle[i]];
1430
1431 for (j = 0; j < ctx->dataSize; j++) {
1432 m = magValues[j]; a = angValues[j];
1433
1434 if (m > 0.0f) {
1435 if (a > 0.0f) { angValues[j] = m - a; }
1436 else {
1437 angValues[j] = m;
1438 magValues[j] = m + a;
1439 }
1440 } else {
1441 if (a > 0.0f) { angValues[j] = m + a; }
1442 else {
1443 angValues[j] = m;
1444 magValues[j] = m - a;
1445 }
1446 }
1447 }
1448 }
1449
1450 /* compute dot product of floor and residue, producing audio spectrum vector */
1451 for (i = 0; i < ctx->channels; i++) {
1452 if (!hasFloor[i]) continue;
1453
1454 submap = mapping->mux[i];
1455 floorIdx = mapping->floorIdx[submap];
1456 Floor_Synthesis(ctx, &ctx->floors[floorIdx], i);
1457 }
1458
1459 /* inverse monolithic transform of audio spectrum vector */
1460 for (i = 0; i < ctx->channels; i++) {
1461 tmp = ctx->curOutput[i];
1462
1463 if (!hasFloor[i]) {
1464 /* TODO: Do we actually need to zero data here (residue type 2 maybe) */
1465 Mem_Set(tmp, 0, ctx->curBlockSize * sizeof(float));
1466 } else {
1467 imdct_calc(tmp, tmp, &ctx->imdct[mode->blockSizeFlag]);
1468 /* defer windowing until output */
1469 }
1470 }
1471
1472 /* discard remaining bits at end of packet */
1473 Vorbis_AlignBits(ctx)alignSkip = ctx->NumBits & 7; ctx->Bits >>= (
alignSkip); ctx->NumBits -= (alignSkip);;
;
1474 return 0;
1475}
1476
1477int Vorbis_OutputFrame(struct VorbisState* ctx, cc_int16* data) {
1478 struct VorbisWindow window;
1479 float* prev[VORBIS_MAX_CHANS8];
1480 float* cur[VORBIS_MAX_CHANS8];
1481
1482 int curQrtr, prevQrtr, overlapQtr;
1483 int curOffset, prevOffset, overlapSize;
1484 float sample;
1485 int i, ch;
1486
1487 /* first frame decoded has no data */
1488 if (ctx->prevBlockSize == 0) {
1489 ctx->prevBlockSize = ctx->curBlockSize;
1490 return 0;
1491 }
1492
1493 /* data returned is from centre of previous block to centre of current block */
1494 /* data is aligned, such that 3/4 of prev block is aligned to 1/4 of cur block */
1495 curQrtr = ctx->curBlockSize / 4;
1496 prevQrtr = ctx->prevBlockSize / 4;
1497 overlapQtr = min(curQrtr, prevQrtr)((curQrtr) < (prevQrtr) ? (curQrtr) : (prevQrtr));
1498
1499 /* So for example, consider a short block overlapping with a long block
1500 a) we need to chop off 'prev' before its halfway point
1501 b) then need to chop off the 'cur' before the halfway point of 'prev'
1502 |- ********|***** |- ********|
1503 -| - * | *** | - * |
1504 - | # | *** ===> | # |
1505 - | * - | *** | * - |
1506 ******-***|* - | *** |* - |
1507 */
1508 curOffset = curQrtr - overlapQtr;
1509 prevOffset = prevQrtr - overlapQtr;
1510
1511 for (i = 0; i < ctx->channels; i++) {
1512 prev[i] = ctx->prevOutput[i] + (prevQrtr * 2);
1513 cur[i] = ctx->curOutput[i];
1514 }
1515
1516 /* for long prev and short cur block, there will be non-overlapped data before */
1517 for (i = 0; i < prevOffset; i++) {
1518 for (ch = 0; ch < ctx->channels; ch++) {
1519 sample = prev[ch][i];
1520 Math_Clamp(sample, -1.0f, 1.0f)sample = sample < (-1.0f) ? (-1.0f) : sample; sample = sample
> (1.0f) ? (1.0f) : sample;
;
1521 *data++ = (cc_int16)(sample * 32767);
1522 }
1523 }
1524
1525 /* adjust pointers to start at 0 for overlapping */
1526 for (i = 0; i < ctx->channels; i++) {
1527 prev[i] += prevOffset; cur[i] += curOffset;
1528 }
1529
1530 overlapSize = overlapQtr * 2;
1531 window = ctx->windows[(overlapQtr * 4) == ctx->blockSizes[1]];
1532
1533 /* overlap and add data */
1534 /* also perform windowing here */
1535 for (i = 0; i < overlapSize; i++) {
1536 for (ch = 0; ch < ctx->channels; ch++) {
1537 sample = prev[ch][i] * window.Prev[i] + cur[ch][i] * window.Cur[i];
1538 Math_Clamp(sample, -1.0f, 1.0f)sample = sample < (-1.0f) ? (-1.0f) : sample; sample = sample
> (1.0f) ? (1.0f) : sample;
;
1539 *data++ = (cc_int16)(sample * 32767);
1540 }
1541 }
1542
1543 /* for long cur and short prev block, there will be non-overlapped data after */
1544 for (i = 0; i < ctx->channels; i++) { cur[i] += overlapSize; }
1545 for (i = 0; i < curOffset; i++) {
1546 for (ch = 0; ch < ctx->channels; ch++) {
1547 sample = cur[ch][i];
1548 Math_Clamp(sample, -1.0f, 1.0f)sample = sample < (-1.0f) ? (-1.0f) : sample; sample = sample
> (1.0f) ? (1.0f) : sample;
;
1549 *data++ = (cc_int16)(sample * 32767);
1550 }
1551 }
1552
1553 ctx->prevBlockSize = ctx->curBlockSize;
1554 return (prevQrtr + curQrtr) * ctx->channels;
1555}