Add a few more reference comments to Vorbis decoder

This commit is contained in:
UnknownShadow200 2023-11-20 19:59:02 +11:00
parent 39b09a9202
commit 27d195ef39
2 changed files with 186 additions and 90 deletions

View File

@ -415,18 +415,19 @@ static struct ChatCommand GpuInfoCommand = {
}; };
static void RenderTypeCommand_Execute(const cc_string* args, int argsCount) { static void RenderTypeCommand_Execute(const cc_string* args, int argsCount) {
char strBuffer[256]; int flags;
cc_string safeStr = String_FromArray(strBuffer); if (!argsCount) {
cc_string unsafeStr; Chat_AddRaw("&e/client: &cYou didn't specify a new render type."); return;
}
Options_SetInt("xyz", 123456); flags = EnvRenderer_CalcFlags(args);
Options_Get("xyz", &safeStr, ""); if (flags >= 0) {
Options_UNSAFE_Get("xyz", &unsafeStr); EnvRenderer_SetMode(flags);
Options_Set(OPT_RENDER_TYPE, args);
Options_Reload(); Chat_Add1("&e/client: &fRender type is now %s.", args);
} else {
Chat_Add1("Safe: %s", &safeStr); Chat_Add1("&e/client: &cUnrecognised render type &f\"%s\"&c.", args);
Chat_Add1("Unsafe: %s", &unsafeStr); }
} }
static struct ChatCommand RenderTypeCommand = { static struct ChatCommand RenderTypeCommand = {

View File

@ -11,6 +11,7 @@
*-------------------------------------------------------Ogg stream--------------------------------------------------------* *-------------------------------------------------------Ogg stream--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#define OGG_FourCC(a, b, c, d) (((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d) #define OGG_FourCC(a, b, c, d) (((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d)
/* See https://xiph.org/ogg/ */
static void Ogg_DiscardPacket(struct OggState* ctx) { static void Ogg_DiscardPacket(struct OggState* ctx) {
ctx->cur += ctx->left; ctx->cur += ctx->left;
@ -141,6 +142,7 @@ void Ogg_Init(struct OggState* ctx, struct Stream* source) {
#define Vorbis_ConsumeBits(ctx, bits) ctx->Bits >>= (bits); ctx->NumBits -= (bits); #define Vorbis_ConsumeBits(ctx, bits) ctx->Bits >>= (bits); ctx->NumBits -= (bits);
/* Aligns bit buffer to be on a byte boundary */ /* Aligns bit buffer to be on a byte boundary */
#define Vorbis_AlignBits(ctx) alignSkip = ctx->NumBits & 7; Vorbis_ConsumeBits(ctx, alignSkip); #define Vorbis_AlignBits(ctx) alignSkip = ctx->NumBits & 7; Vorbis_ConsumeBits(ctx, alignSkip);
/* See https://xiph.org/vorbis/doc/Vorbis_I_spec.html */
/* TODO: Make sure this is inlined */ /* TODO: Make sure this is inlined */
static cc_uint32 Vorbis_ReadBits(struct VorbisState* ctx, cc_uint32 bitsCount) { static cc_uint32 Vorbis_ReadBits(struct VorbisState* ctx, cc_uint32 bitsCount) {
@ -188,6 +190,7 @@ static cc_uint32 Vorbis_ReadBit(struct VorbisState* ctx) {
} }
/* Vorbis spec 9.2.1. ilog */
static int iLog(int x) { static int iLog(int x) {
int bits = 0; int bits = 0;
while (x > 0) { bits++; x >>= 1; } while (x > 0) { bits++; x >>= 1; }
@ -225,6 +228,7 @@ static float Fast_ldexpf(int m, int exp) {
return raw.f; return raw.f;
} }
/* Vorbis spec 9.2.2. float32_unpack */
static float float32_unpack(struct VorbisState* ctx) { static float float32_unpack(struct VorbisState* ctx) {
/* ReadBits can't reliably read over 24 bits */ /* ReadBits can't reliably read over 24 bits */
cc_uint32 lo = Vorbis_ReadBits(ctx, 16); cc_uint32 lo = Vorbis_ReadBits(ctx, 16);
@ -242,7 +246,9 @@ static float float32_unpack(struct VorbisState* ctx) {
/*########################################################################################################################* /*########################################################################################################################*
*----------------------------------------------------Vorbis codebooks-----------------------------------------------------* *----------------------------------------------------Vorbis codebooks-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
/* Vorbis spec 3. Probability Model and Codebooks */
#define CODEBOOK_SYNC 0x564342 #define CODEBOOK_SYNC 0x564342
struct Codebook { struct Codebook {
cc_uint32 dimensions, entries, totalCodewords; cc_uint32 dimensions, entries, totalCodewords;
cc_uint32* codewords; cc_uint32* codewords;
@ -274,7 +280,8 @@ static cc_uint32 Codebook_Lookup1Values(cc_uint32 entries, cc_uint32 dimensions)
cc_uint32 i, pow, next; cc_uint32 i, pow, next;
/* the greatest integer value for which [value] to the power of [dimensions] is less than or equal to [entries] */ /* the greatest integer value for which [value] to the power of [dimensions] is less than or equal to [entries] */
/* TODO: verify this */ /* TODO: verify this */
for (i = 1; ; i++) { for (i = 1; ; i++)
{
pow = Codebook_Pow(i, dimensions); pow = Codebook_Pow(i, dimensions);
next = Codebook_Pow(i + 1, dimensions); next = Codebook_Pow(i + 1, dimensions);
@ -298,13 +305,15 @@ static cc_bool Codebook_CalcCodewords(struct Codebook* c, cc_uint8* len) {
/* Codeword entries are ordered by length */ /* Codeword entries are ordered by length */
offset = 0; offset = 0;
for (i = 0; i < Array_Elems(len_offsets); i++) { for (i = 0; i < Array_Elems(len_offsets); i++)
{
len_offsets[i] = offset; len_offsets[i] = offset;
offset += c->numCodewords[i]; offset += c->numCodewords[i];
} }
/* add codeword 0 to tree */ /* add codeword 0 to tree */
for (i = 0; i < c->entries; i++) { for (i = 0; i < c->entries; i++)
{
if (!len[i]) continue; if (!len[i]) continue;
offset = len_offsets[len[i]]; offset = len_offsets[len[i]];
@ -316,12 +325,14 @@ static cc_bool Codebook_CalcCodewords(struct Codebook* c, cc_uint8* len) {
} }
/* set codewords that new nodes can start from */ /* set codewords that new nodes can start from */
for (depth = 1; depth <= len[i]; depth++) { for (depth = 1; depth <= len[i]; depth++)
{
next_codewords[depth] = 1U << (32 - depth); next_codewords[depth] = 1U << (32 - depth);
} }
i++; /* first codeword was already handled */ i++; /* first codeword was already handled */
for (; i < c->entries; i++) { for (; i < c->entries; i++)
{
root = len[i]; root = len[i];
if (!root) continue; if (!root) continue;
offset = len_offsets[len[i]]; offset = len_offsets[len[i]];
@ -336,7 +347,8 @@ static cc_bool Codebook_CalcCodewords(struct Codebook* c, cc_uint8* len) {
c->codewords[offset] = codeword; c->codewords[offset] = codeword;
c->values[offset] = i; c->values[offset] = i;
for (depth = len[i]; depth > root; depth--) { for (depth = len[i]; depth > root; depth--)
{
next_codewords[depth] = codeword + (1U << (32 - depth)); next_codewords[depth] = codeword + (1U << (32 - depth));
} }
@ -360,7 +372,8 @@ static cc_result Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
c->entries = Vorbis_ReadBits(ctx, 24); c->entries = Vorbis_ReadBits(ctx, 24);
codewordLens = (cc_uint8*)Mem_Alloc(c->entries, 1, "raw codeword lens"); codewordLens = (cc_uint8*)Mem_Alloc(c->entries, 1, "raw codeword lens");
for (i = 0; i < Array_Elems(c->numCodewords); i++) { for (i = 0; i < Array_Elems(c->numCodewords); i++)
{
c->numCodewords[i] = 0; c->numCodewords[i] = 0;
} }
@ -368,7 +381,8 @@ static cc_result Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
if (!Vorbis_ReadBit(ctx)) { if (!Vorbis_ReadBit(ctx)) {
sparse = Vorbis_ReadBit(ctx); sparse = Vorbis_ReadBit(ctx);
entry = 0; entry = 0;
for (i = 0; i < c->entries; i++) { for (i = 0; i < c->entries; i++)
{
/* sparse trees may not have all entries */ /* sparse trees may not have all entries */
if (sparse && !Vorbis_ReadBit(ctx)){ if (sparse && !Vorbis_ReadBit(ctx)){
codewordLens[i] = 0; codewordLens[i] = 0;
@ -382,7 +396,8 @@ static cc_result Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
} }
} else { } else {
len = Vorbis_ReadBits(ctx, 5) + 1; len = Vorbis_ReadBits(ctx, 5) + 1;
for (entry = 0; entry < c->entries;) { for (entry = 0; entry < c->entries;)
{
runBits = iLog(c->entries - entry); runBits = iLog(c->entries - entry);
runLen = Vorbis_ReadBits(ctx, runBits); runLen = Vorbis_ReadBits(ctx, runBits);
@ -416,7 +431,8 @@ static cc_result Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
c->lookupValues = lookupValues; c->lookupValues = lookupValues;
c->multiplicands = (cc_uint16*)Mem_Alloc(lookupValues, 2, "multiplicands"); c->multiplicands = (cc_uint16*)Mem_Alloc(lookupValues, 2, "multiplicands");
for (i = 0; i < lookupValues; i++) { for (i = 0; i < lookupValues; i++)
{
c->multiplicands[i] = Vorbis_ReadBits(ctx, valueBits); c->multiplicands[i] = Vorbis_ReadBits(ctx, valueBits);
} }
return 0; return 0;
@ -428,10 +444,12 @@ static cc_uint32 Codebook_DecodeScalar(struct VorbisState* ctx, struct Codebook*
cc_uint32* values = c->values; cc_uint32* values = c->values;
/* TODO: This is so massively slow */ /* TODO: This is so massively slow */
for (depth = 1; depth <= 32; depth++, shift--) { for (depth = 1; depth <= 32; depth++, shift--)
{
codeword |= Vorbis_ReadBit(ctx) << shift; codeword |= Vorbis_ReadBit(ctx) << shift;
for (i = 0; i < c->numCodewords[depth]; i++) { for (i = 0; i < c->numCodewords[depth]; i++)
{
if (codeword != codewords[i]) continue; if (codeword != codewords[i]) continue;
return values[i]; return values[i];
} }
@ -450,7 +468,8 @@ static void Codebook_DecodeVectors(struct VorbisState* ctx, struct Codebook* c,
if (c->lookupType == 1) { if (c->lookupType == 1) {
cc_uint32 indexDivisor = 1; cc_uint32 indexDivisor = 1;
for (i = 0; i < c->dimensions; i++, v += step) { for (i = 0; i < c->dimensions; i++, v += step)
{
offset = (lookupOffset / indexDivisor) % c->lookupValues; offset = (lookupOffset / indexDivisor) % c->lookupValues;
value = c->multiplicands[offset] * c->deltaValue + c->minValue + last; value = c->multiplicands[offset] * c->deltaValue + c->minValue + last;
@ -460,7 +479,8 @@ static void Codebook_DecodeVectors(struct VorbisState* ctx, struct Codebook* c,
} }
} else if (c->lookupType == 2) { } else if (c->lookupType == 2) {
offset = lookupOffset * c->dimensions; offset = lookupOffset * c->dimensions;
for (i = 0; i < c->dimensions; i++, offset++, v += step) { for (i = 0; i < c->dimensions; i++, offset++, v += step)
{
value = c->multiplicands[offset] * c->deltaValue + c->minValue + last; value = c->multiplicands[offset] * c->deltaValue + c->minValue + last;
*v += value; *v += value;
@ -489,6 +509,7 @@ struct Floor {
cc_int32 yList[VORBIS_MAX_CHANS][FLOOR_MAX_VALUES]; cc_int32 yList[VORBIS_MAX_CHANS][FLOOR_MAX_VALUES];
}; };
/* Vorbis spec 10.1. floor1_inverse_dB_table */
static const float floor1_inverse_dB_table[256] = { static const float floor1_inverse_dB_table[256] = {
1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f,
1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f,
@ -554,19 +575,22 @@ static cc_result Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
f->partitions = Vorbis_ReadBits(ctx, 5); f->partitions = Vorbis_ReadBits(ctx, 5);
maxClass = -1; maxClass = -1;
for (i = 0; i < f->partitions; i++) { for (i = 0; i < f->partitions; i++)
{
f->partitionClasses[i] = Vorbis_ReadBits(ctx, 4); f->partitionClasses[i] = Vorbis_ReadBits(ctx, 4);
maxClass = max(maxClass, f->partitionClasses[i]); maxClass = max(maxClass, f->partitionClasses[i]);
} }
for (i = 0; i <= maxClass; i++) { for (i = 0; i <= maxClass; i++)
{
f->classDimensions[i] = Vorbis_ReadBits(ctx, 3) + 1; f->classDimensions[i] = Vorbis_ReadBits(ctx, 3) + 1;
f->classSubClasses[i] = Vorbis_ReadBits(ctx, 2); f->classSubClasses[i] = Vorbis_ReadBits(ctx, 2);
if (f->classSubClasses[i]) { if (f->classSubClasses[i]) {
f->classMasterbooks[i] = Vorbis_ReadBits(ctx, 8); f->classMasterbooks[i] = Vorbis_ReadBits(ctx, 8);
} }
for (j = 0; j < (1 << f->classSubClasses[i]); j++) { for (j = 0; j < (1 << f->classSubClasses[i]); j++)
{
f->subclassBooks[i][j] = (cc_int16)Vorbis_ReadBits(ctx, 8) - 1; f->subclassBooks[i][j] = (cc_int16)Vorbis_ReadBits(ctx, 8) - 1;
} }
} }
@ -577,10 +601,12 @@ static cc_result Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
f->xList[0] = 0; f->xList[0] = 0;
f->xList[1] = 1 << rangeBits; f->xList[1] = 1 << rangeBits;
for (i = 0, idx = 2; i < f->partitions; i++) { for (i = 0, idx = 2; i < f->partitions; i++)
{
classNum = f->partitionClasses[i]; classNum = f->partitionClasses[i];
for (j = 0; j < f->classDimensions[classNum]; j++) { for (j = 0; j < f->classDimensions[classNum]; j++)
{
f->xList[idx++] = Vorbis_ReadBits(ctx, rangeBits); f->xList[idx++] = Vorbis_ReadBits(ctx, rangeBits);
} }
} }
@ -611,7 +637,8 @@ static cc_bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, int c
yList[0] = Vorbis_ReadBits(ctx, rangeBits); yList[0] = Vorbis_ReadBits(ctx, rangeBits);
yList[1] = Vorbis_ReadBits(ctx, rangeBits); yList[1] = Vorbis_ReadBits(ctx, rangeBits);
for (i = 0, idx = 2; i < f->partitions; i++) { for (i = 0, idx = 2; i < f->partitions; i++)
{
klass = f->partitionClasses[i]; klass = f->partitionClasses[i];
cdim = f->classDimensions[klass]; cdim = f->classDimensions[klass];
cbits = f->classSubClasses[klass]; cbits = f->classSubClasses[klass];
@ -623,7 +650,8 @@ static cc_bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, int c
cval = Codebook_DecodeScalar(ctx, &ctx->codebooks[bookNum]); cval = Codebook_DecodeScalar(ctx, &ctx->codebooks[bookNum]);
} }
for (j = 0; j < cdim; j++) { for (j = 0; j < cdim; j++)
{
bookNum = f->subclassBooks[klass][cval & csub]; bookNum = f->subclassBooks[klass][cval & csub];
cval >>= cbits; cval >>= cbits;
@ -638,6 +666,7 @@ static cc_bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, int c
return true; return true;
} }
/* Vorbis spec 9.2.6. render_point */
static int Floor_RenderPoint(int x0, int y0, int x1, int y1, int X) { static int Floor_RenderPoint(int x0, int y0, int x1, int y1, int X) {
int dy = y1 - y0, adx = x1 - x0; int dy = y1 - y0, adx = x1 - x0;
int ady = Math_AbsI(dy); int ady = Math_AbsI(dy);
@ -651,6 +680,7 @@ static int Floor_RenderPoint(int x0, int y0, int x1, int y1, int X) {
} }
} }
/* Vorbis spec 9.2.7. render_line */
static void Floor_RenderLine(int x0, int y0, int x1, int y1, float* data) { static void Floor_RenderLine(int x0, int y0, int x1, int y1, float* data) {
int dy = y1 - y0, adx = x1 - x0; int dy = y1 - y0, adx = x1 - x0;
int ady = Math_AbsI(dy); int ady = Math_AbsI(dy);
@ -678,17 +708,21 @@ static void Floor_RenderLine(int x0, int y0, int x1, int y1, float* data) {
} }
} }
/* Vorbis spec 9.2.4. low_neighbor */
static int low_neighbor(cc_int16* v, int x) { static int low_neighbor(cc_int16* v, int x) {
int n = 0, i, max = Int32_MinValue; int n = 0, i, max = Int32_MinValue;
for (i = 0; i < x; i++) { for (i = 0; i < x; i++)
{
if (v[i] < v[x] && v[i] > max) { n = i; max = v[i]; } if (v[i] < v[x] && v[i] > max) { n = i; max = v[i]; }
} }
return n; return n;
} }
/* Vorbis spec 9.2.5. high_neighbor */
static int high_neighbor(cc_int16* v, int x) { static int high_neighbor(cc_int16* v, int x) {
int n = 0, i, min = Int32_MaxValue; int n = 0, i, min = Int32_MaxValue;
for (i = 0; i < x; i++) { for (i = 0; i < x; i++)
{
if (v[i] > v[x] && v[i] < min) { n = i; min = v[i]; } if (v[i] > v[x] && v[i] < min) { n = i; min = v[i]; }
} }
return n; return n;
@ -718,7 +752,8 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, int ch) {
YFinal[0] = yList[0]; YFinal[0] = yList[0];
YFinal[1] = yList[1]; YFinal[1] = yList[1];
for (i = 2; i < f->values; i++) { for (i = 2; i < f->values; i++)
{
lo_offset = low_neighbor(f->xList, i); lo_offset = low_neighbor(f->xList, i);
hi_offset = high_neighbor(f->xList, i); hi_offset = high_neighbor(f->xList, i);
predicted = Floor_RenderPoint(f->xList[lo_offset], YFinal[lo_offset], predicted = Floor_RenderPoint(f->xList[lo_offset], YFinal[lo_offset],
@ -762,7 +797,8 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, int ch) {
lx = 0; ly = YFinal[f->listOrder[0]] * f->multiplier; lx = 0; ly = YFinal[f->listOrder[0]] * f->multiplier;
hx = 0; hy = ly; hx = 0; hy = ly;
for (rawI = 1; rawI < f->values; rawI++) { for (rawI = 1; rawI < f->values; rawI++)
{
i = f->listOrder[rawI]; i = f->listOrder[rawI];
if (!Step2[i]) continue; if (!Step2[i]) continue;
@ -805,14 +841,17 @@ static cc_result Residue_DecodeSetup(struct VorbisState* ctx, struct Residue* r,
r->classifications = Vorbis_ReadBits(ctx, 6) + 1; r->classifications = Vorbis_ReadBits(ctx, 6) + 1;
r->classbook = Vorbis_ReadBits(ctx, 8); r->classbook = Vorbis_ReadBits(ctx, 8);
for (i = 0; i < r->classifications; i++) { for (i = 0; i < r->classifications; i++)
{
r->cascade[i] = Vorbis_ReadBits(ctx, 3); r->cascade[i] = Vorbis_ReadBits(ctx, 3);
if (!Vorbis_ReadBit(ctx)) continue; if (!Vorbis_ReadBit(ctx)) continue;
r->cascade[i] |= Vorbis_ReadBits(ctx, 5) << 3; r->cascade[i] |= Vorbis_ReadBits(ctx, 5) << 3;
} }
for (i = 0; i < r->classifications; i++) { for (i = 0; i < r->classifications; i++)
for (j = 0; j < 8; j++) { {
for (j = 0; j < 8; j++)
{
codebook = -1; codebook = -1;
if (r->cascade[i] & (1 << j)) { if (r->cascade[i] & (1 << j)) {
@ -854,31 +893,37 @@ static void Residue_DecodeCore(struct VorbisState* ctx, struct Residue* r, cc_ui
/* first half of temp array is used by residue type 2 for storing temp interleaved data */ /* first half of temp array is used by residue type 2 for storing temp interleaved data */
classifications_raw = ((cc_uint8*)ctx->temp) + (ctx->dataSize * ctx->channels * 5); classifications_raw = ((cc_uint8*)ctx->temp) + (ctx->dataSize * ctx->channels * 5);
for (i = 0; i < ch; i++) { for (i = 0; i < ch; i++)
{
/* add a bit of space in case classwordsPerCodeword is > partitionsToRead*/ /* add a bit of space in case classwordsPerCodeword is > partitionsToRead*/
classifications[i] = classifications_raw + i * (partitionsToRead + 64); classifications[i] = classifications_raw + i * (partitionsToRead + 64);
} }
if (nToRead == 0) return; if (nToRead == 0) return;
for (pass = 0; pass < 8; pass++) { for (pass = 0; pass < 8; pass++)
{
cc_uint32 partitionCount = 0; cc_uint32 partitionCount = 0;
while (partitionCount < partitionsToRead) { while (partitionCount < partitionsToRead) {
/* read classifications in pass 0 */ /* read classifications in pass 0 */
if (pass == 0) { if (pass == 0) {
for (j = 0; j < ch; j++) { for (j = 0; j < ch; j++)
{
if (doNotDecode[j]) continue; if (doNotDecode[j]) continue;
temp = Codebook_DecodeScalar(ctx, classbook); temp = Codebook_DecodeScalar(ctx, classbook);
for (i = classwordsPerCodeword - 1; i >= 0; i--) { for (i = classwordsPerCodeword - 1; i >= 0; i--)
{
classifications[j][i + partitionCount] = temp % r->classifications; classifications[j][i + partitionCount] = temp % r->classifications;
temp /= r->classifications; temp /= r->classifications;
} }
} }
} }
for (i = 0; i < classwordsPerCodeword && partitionCount < partitionsToRead; i++) { for (i = 0; i < classwordsPerCodeword && partitionCount < partitionsToRead; i++)
for (j = 0; j < ch; j++) { {
for (j = 0; j < ch; j++)
{
if (doNotDecode[j]) continue; if (doNotDecode[j]) continue;
klass = classifications[j][partitionCount]; klass = classifications[j][partitionCount];
@ -891,11 +936,13 @@ static void Residue_DecodeCore(struct VorbisState* ctx, struct Residue* r, cc_ui
if (r->type == 0) { if (r->type == 0) {
int step = r->partitionSize / c->dimensions; int step = r->partitionSize / c->dimensions;
for (k = 0; k < step; k++) { for (k = 0; k < step; k++)
{
Codebook_DecodeVectors(ctx, c, v, step); v++; Codebook_DecodeVectors(ctx, c, v, step); v++;
} }
} else { } else {
for (k = 0; k < r->partitionSize; k += c->dimensions) { for (k = 0; k < r->partitionSize; k += c->dimensions)
{
Codebook_DecodeVectors(ctx, c, v, 1); v += c->dimensions; Codebook_DecodeVectors(ctx, c, v, 1); v += c->dimensions;
} }
} }
@ -916,7 +963,8 @@ static void Residue_DecodeFrame(struct VorbisState* ctx, struct Residue* r, int
decodeAny = false; decodeAny = false;
/* type 2 decodes all channel vectors, if at least 1 channel to decode */ /* type 2 decodes all channel vectors, if at least 1 channel to decode */
for (i = 0; i < ch; i++) { for (i = 0; i < ch; i++)
{
if (!doNotDecode[i]) decodeAny = true; if (!doNotDecode[i]) decodeAny = true;
} }
if (!decodeAny) return; if (!decodeAny) return;
@ -929,8 +977,10 @@ static void Residue_DecodeFrame(struct VorbisState* ctx, struct Residue* r, int
Residue_DecodeCore(ctx, r, size * ch, 1, &decodeAny, &interleaved); Residue_DecodeCore(ctx, r, size * ch, 1, &decodeAny, &interleaved);
/* deinterleave type 2 output */ /* deinterleave type 2 output */
for (i = 0; i < size; i++) { for (i = 0; i < size; i++)
for (j = 0; j < ch; j++) { {
for (j = 0; j < ch; j++)
{
data[j][i] = interleaved[i * ch + j]; data[j][i] = interleaved[i * ch + j];
} }
} }
@ -969,7 +1019,8 @@ static cc_result Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m)
/* TODO: How big can couplingSteps ever really get in practice? */ /* TODO: How big can couplingSteps ever really get in practice? */
couplingBits = iLog(ctx->channels - 1); couplingBits = iLog(ctx->channels - 1);
for (i = 0; i < couplingSteps; i++) { for (i = 0; i < couplingSteps; i++)
{
m->magnitude[i] = Vorbis_ReadBits(ctx, couplingBits); m->magnitude[i] = Vorbis_ReadBits(ctx, couplingBits);
m->angle[i] = Vorbis_ReadBits(ctx, couplingBits); m->angle[i] = Vorbis_ReadBits(ctx, couplingBits);
if (m->magnitude[i] == m->angle[i]) return VORBIS_ERR_MAPPING_CHANS; if (m->magnitude[i] == m->angle[i]) return VORBIS_ERR_MAPPING_CHANS;
@ -982,16 +1033,19 @@ static cc_result Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m)
m->couplingSteps = couplingSteps; m->couplingSteps = couplingSteps;
if (submaps > 1) { if (submaps > 1) {
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
m->mux[i] = Vorbis_ReadBits(ctx, 4); m->mux[i] = Vorbis_ReadBits(ctx, 4);
} }
} else { } else {
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
m->mux[i] = 0; m->mux[i] = 0;
} }
} }
for (i = 0; i < submaps; i++) { for (i = 0; i < submaps; i++)
{
Vorbis_ReadBits(ctx, 8); /* time value */ Vorbis_ReadBits(ctx, 8); /* time value */
m->floorIdx[i] = Vorbis_ReadBits(ctx, 8); m->floorIdx[i] = Vorbis_ReadBits(ctx, 8);
m->residueIdx[i] = Vorbis_ReadBits(ctx, 8); m->residueIdx[i] = Vorbis_ReadBits(ctx, 8);
@ -1023,18 +1077,21 @@ void imdct_init(struct imdct_state* state, int n) {
state->n = n; state->log2_n = log2_n; state->n = n; state->log2_n = log2_n;
/* setup twiddle factors */ /* setup twiddle factors */
for (k = 0, k2 = 0; k < n4; k++, k2 += 2) { for (k = 0, k2 = 0; k < n4; k++, k2 += 2)
{
A[k2] = (float)Math_Cos((4*k * PI) / n); A[k2] = (float)Math_Cos((4*k * PI) / n);
A[k2+1] = -(float)Math_Sin((4*k * PI) / n); A[k2+1] = -(float)Math_Sin((4*k * PI) / n);
B[k2] = (float)Math_Cos(((k2+1) * PI) / (2*n)); B[k2] = (float)Math_Cos(((k2+1) * PI) / (2*n));
B[k2+1] = (float)Math_Sin(((k2+1) * PI) / (2*n)); B[k2+1] = (float)Math_Sin(((k2+1) * PI) / (2*n));
} }
for (k = 0, k2 = 0; k < n8; k++, k2 += 2) { for (k = 0, k2 = 0; k < n8; k++, k2 += 2)
{
C[k2] = (float)Math_Cos(((k2+1) * (2*PI)) / n); C[k2] = (float)Math_Cos(((k2+1) * (2*PI)) / n);
C[k2+1] = -(float)Math_Sin(((k2+1) * (2*PI)) / n); C[k2+1] = -(float)Math_Sin(((k2+1) * (2*PI)) / n);
} }
for (k = 0; k < n8; k++) { for (k = 0; k < n8; k++)
{
reversed[k] = Vorbis_ReverseBits(k) >> (32-log2_n+3); reversed[k] = Vorbis_ReverseBits(k) >> (32-log2_n+3);
} }
} }
@ -1057,7 +1114,8 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
/* spectral coefficients, step 1, step 2 */ /* TODO avoid k */ /* spectral coefficients, step 1, step 2 */ /* TODO avoid k */
for (k = 0, k2 = 0, k4 = 0; k < n8; k++, k2 += 2, k4 += 4) { for (k = 0, k2 = 0, k4 = 0; k < n8; k++, k2 += 2, k4 += 4)
{
e_1 = -in[k4+3]; e_2 = -in[k4+1]; e_1 = -in[k4+3]; e_2 = -in[k4+1];
g_1 = e_1 * A[n2-1-k2] + e_2 * A[n2-2-k2]; g_1 = e_1 * A[n2-1-k2] + e_2 * A[n2-2-k2];
g_2 = e_1 * A[n2-2-k2] - e_2 * A[n2-1-k2]; g_2 = e_1 * A[n2-2-k2] - e_2 * A[n2-1-k2];
@ -1075,12 +1133,15 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
/* step 3 */ /* step 3 */
log2_n = state->log2_n; log2_n = state->log2_n;
for (l = 0; l <= log2_n - 4; l++) { for (l = 0; l <= log2_n - 4; l++)
{
int k0 = n >> (l+3), k1 = 1 << (l+3); int k0 = n >> (l+3), k1 = 1 << (l+3);
int r, r2, rMax = n >> (l+4), s2, s2Max = 1 << (l+2); int r, r2, rMax = n >> (l+4), s2, s2Max = 1 << (l+2);
for (r = 0, r2 = 0; r < rMax; r++, r2 += 2) { for (r = 0, r2 = 0; r < rMax; r++, r2 += 2)
for (s2 = 0; s2 < s2Max; s2 += 2) { {
for (s2 = 0; s2 < s2Max; s2 += 2)
{
e_1 = w[n2-1-k0*s2-r2]; e_1 = w[n2-1-k0*s2-r2];
e_2 = w[n2-2-k0*s2-r2]; e_2 = w[n2-2-k0*s2-r2];
f_1 = w[n2-1-k0*(s2+1)-r2]; f_1 = w[n2-1-k0*(s2+1)-r2];
@ -1102,7 +1163,8 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
/* step 4, step 5, step 6, step 7, step 8, output */ /* step 4, step 5, step 6, step 7, step 8, output */
reversed = state->reversed; reversed = state->reversed;
for (k = 0, k2 = 0; k < n8; k++, k2 += 2) { for (k = 0, k2 = 0; k < n8; k++, k2 += 2)
{
cc_uint32 j = reversed[k], j4 = j << 2; cc_uint32 j = reversed[k], j4 = j << 2;
e_1 = u[n2-j4-1]; e_2 = u[n2-j4-2]; e_1 = u[n2-j4-1]; e_2 = u[n2-j4-2];
f_1 = u[j4+1]; f_2 = u[j4+0]; f_1 = u[j4+1]; f_2 = u[j4+0];
@ -1155,11 +1217,13 @@ static void Vorbis_CalcWindow(struct VorbisWindow* window, int blockSize) {
cur_window = window->Cur; cur_window = window->Cur;
prev_window = window->Prev; prev_window = window->Prev;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++)
{
inner = Math_Sin((i + 0.5) / n * (PI/2)); inner = Math_Sin((i + 0.5) / n * (PI/2));
cur_window[i] = Math_Sin((PI/2) * inner * inner); cur_window[i] = Math_Sin((PI/2) * inner * inner);
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++)
{
inner = Math_Sin((i + 0.5) / n * (PI/2) + (PI/2)); inner = Math_Sin((i + 0.5) / n * (PI/2) + (PI/2));
prev_window[i] = Math_Sin((PI/2) * inner * inner); prev_window[i] = Math_Sin((PI/2) * inner * inner);
} }
@ -1167,7 +1231,8 @@ static void Vorbis_CalcWindow(struct VorbisWindow* window, int blockSize) {
void Vorbis_Free(struct VorbisState* ctx) { void Vorbis_Free(struct VorbisState* ctx) {
int i; int i;
for (i = 0; i < ctx->numCodebooks; i++) { for (i = 0; i < ctx->numCodebooks; i++)
{
Codebook_Free(&ctx->codebooks[i]); Codebook_Free(&ctx->codebooks[i]);
} }
@ -1184,6 +1249,7 @@ static cc_bool Vorbis_ValidBlockSize(cc_uint32 size) {
return size >= 64 && size <= VORBIS_MAX_BLOCK_SIZE && Math_IsPowOf2(size); return size >= 64 && size <= VORBIS_MAX_BLOCK_SIZE && Math_IsPowOf2(size);
} }
/* Vorbis spec 4.2.1. Common header decode */
static cc_result Vorbis_CheckHeader(struct VorbisState* ctx, cc_uint8 type) { static cc_result Vorbis_CheckHeader(struct VorbisState* ctx, cc_uint8 type) {
cc_uint8 header[7]; cc_uint8 header[7];
cc_bool OK; cc_bool OK;
@ -1198,6 +1264,7 @@ static cc_result Vorbis_CheckHeader(struct VorbisState* ctx, cc_uint8 type) {
return OK ? 0 : ERR_INVALID_ARGUMENT; return OK ? 0 : ERR_INVALID_ARGUMENT;
} }
/* Vorbis spec 4.2.2. Identification header */
static cc_result Vorbis_DecodeIdentifier(struct VorbisState* ctx) { static cc_result Vorbis_DecodeIdentifier(struct VorbisState* ctx) {
cc_uint8 header[23]; cc_uint8 header[23];
cc_uint32 version; cc_uint32 version;
@ -1222,6 +1289,7 @@ static cc_result Vorbis_DecodeIdentifier(struct VorbisState* ctx) {
return (header[22] & 1) ? 0 : VORBIS_ERR_FRAMING; return (header[22] & 1) ? 0 : VORBIS_ERR_FRAMING;
} }
/* Vorbis spec 4.2.3. Comment header */
static cc_result Vorbis_DecodeComments(struct VorbisState* ctx) { static cc_result Vorbis_DecodeComments(struct VorbisState* ctx) {
cc_uint32 i, len, comments; cc_uint32 i, len, comments;
cc_uint8 flag; cc_uint8 flag;
@ -1233,7 +1301,8 @@ static cc_result Vorbis_DecodeComments(struct VorbisState* ctx) {
if ((res = Ogg_Skip(source, len))) return res; if ((res = Ogg_Skip(source, len))) return res;
if ((res = Ogg_ReadU32(source, &comments))) return res; if ((res = Ogg_ReadU32(source, &comments))) return res;
for (i = 0; i < comments; i++) { for (i = 0; i < comments; i++)
{
/* comments such as artist, year, etc */ /* comments such as artist, year, etc */
if ((res = Ogg_ReadU32(source, &len))) return res; if ((res = Ogg_ReadU32(source, &len))) return res;
if ((res = Ogg_Skip(source, len))) return res; if ((res = Ogg_Skip(source, len))) return res;
@ -1244,6 +1313,7 @@ static cc_result Vorbis_DecodeComments(struct VorbisState* ctx) {
return (flag & 1) ? 0 : VORBIS_ERR_FRAMING; return (flag & 1) ? 0 : VORBIS_ERR_FRAMING;
} }
/* Vorbis spec 4.2.4. Setup header */
static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) { static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
cc_uint32 framing, alignSkip; cc_uint32 framing, alignSkip;
int i, count; int i, count;
@ -1253,14 +1323,16 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
ctx->codebooks = (struct Codebook*)Mem_TryAlloc(count, sizeof(struct Codebook)); ctx->codebooks = (struct Codebook*)Mem_TryAlloc(count, sizeof(struct Codebook));
if (!ctx->codebooks) return ERR_OUT_OF_MEMORY; if (!ctx->codebooks) return ERR_OUT_OF_MEMORY;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
res = Codebook_DecodeSetup(ctx, &ctx->codebooks[i]); res = Codebook_DecodeSetup(ctx, &ctx->codebooks[i]);
if (res) return res; if (res) return res;
} }
ctx->numCodebooks = count; ctx->numCodebooks = count;
count = Vorbis_ReadBits(ctx, 6) + 1; count = Vorbis_ReadBits(ctx, 6) + 1;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
int time = Vorbis_ReadBits(ctx, 16); int time = Vorbis_ReadBits(ctx, 16);
if (time != 0) return VORBIS_ERR_TIME_TYPE; if (time != 0) return VORBIS_ERR_TIME_TYPE;
} }
@ -1269,7 +1341,8 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
ctx->floors = (struct Floor*)Mem_TryAlloc(count, sizeof(struct Floor)); ctx->floors = (struct Floor*)Mem_TryAlloc(count, sizeof(struct Floor));
if (!ctx->floors) return ERR_OUT_OF_MEMORY; if (!ctx->floors) return ERR_OUT_OF_MEMORY;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
int floor = Vorbis_ReadBits(ctx, 16); int floor = Vorbis_ReadBits(ctx, 16);
if (floor != 1) return VORBIS_ERR_FLOOR_TYPE; if (floor != 1) return VORBIS_ERR_FLOOR_TYPE;
@ -1281,7 +1354,8 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
ctx->residues = (struct Residue*)Mem_TryAlloc(count, sizeof(struct Residue)); ctx->residues = (struct Residue*)Mem_TryAlloc(count, sizeof(struct Residue));
if (!ctx->residues) return ERR_OUT_OF_MEMORY; if (!ctx->residues) return ERR_OUT_OF_MEMORY;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
int residue = Vorbis_ReadBits(ctx, 16); int residue = Vorbis_ReadBits(ctx, 16);
if (residue > 2) return VORBIS_ERR_FLOOR_TYPE; if (residue > 2) return VORBIS_ERR_FLOOR_TYPE;
@ -1293,7 +1367,8 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
ctx->mappings = (struct Mapping*)Mem_TryAlloc(count, sizeof(struct Mapping)); ctx->mappings = (struct Mapping*)Mem_TryAlloc(count, sizeof(struct Mapping));
if (!ctx->mappings) return ERR_OUT_OF_MEMORY; if (!ctx->mappings) return ERR_OUT_OF_MEMORY;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
int mapping = Vorbis_ReadBits(ctx, 16); int mapping = Vorbis_ReadBits(ctx, 16);
if (mapping != 0) return VORBIS_ERR_MAPPING_TYPE; if (mapping != 0) return VORBIS_ERR_MAPPING_TYPE;
@ -1305,7 +1380,8 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
ctx->modes = (struct Mode*)Mem_TryAlloc(count, sizeof(struct Mode)); ctx->modes = (struct Mode*)Mem_TryAlloc(count, sizeof(struct Mode));
if (!ctx->modes) return ERR_OUT_OF_MEMORY; if (!ctx->modes) return ERR_OUT_OF_MEMORY;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
res = Mode_DecodeSetup(ctx, &ctx->modes[i]); res = Mode_DecodeSetup(ctx, &ctx->modes[i]);
if (res) return res; if (res) return res;
} }
@ -1317,6 +1393,7 @@ static cc_result Vorbis_DecodeSetup(struct VorbisState* ctx) {
return (framing & 1) ? 0 : VORBIS_ERR_FRAMING; return (framing & 1) ? 0 : VORBIS_ERR_FRAMING;
} }
/* Vorbis spec 4.2. Header decode and decode setup */
cc_result Vorbis_DecodeHeaders(struct VorbisState* ctx) { cc_result Vorbis_DecodeHeaders(struct VorbisState* ctx) {
cc_uint32 count; cc_uint32 count;
cc_result res; cc_result res;
@ -1360,6 +1437,7 @@ cc_result Vorbis_DecodeHeaders(struct VorbisState* ctx) {
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------Vorbis frame--------------------------------------------------------* *-----------------------------------------------------Vorbis frame--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
/* Vorbis spec 4.3. Audio packet decode and synthesis */
cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) { cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
/* frame header */ /* frame header */
cc_uint32 packetType; cc_uint32 packetType;
@ -1404,13 +1482,15 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
tmp = ctx->values[1]; ctx->values[1] = ctx->values[0]; ctx->values[0] = tmp; tmp = ctx->values[1]; ctx->values[1] = ctx->values[0]; ctx->values[0] = tmp;
Mem_Set(ctx->values[0], 0, ctx->channels * ctx->curBlockSize); Mem_Set(ctx->values[0], 0, ctx->channels * ctx->curBlockSize);
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
ctx->curOutput[i] = ctx->values[0] + i * ctx->curBlockSize; ctx->curOutput[i] = ctx->values[0] + i * ctx->curBlockSize;
ctx->prevOutput[i] = ctx->values[1] + i * ctx->prevBlockSize; ctx->prevOutput[i] = ctx->values[1] + i * ctx->prevBlockSize;
} }
/* decode floor */ /* decode floor */
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
submap = mapping->mux[i]; submap = mapping->mux[i];
floorIdx = mapping->floorIdx[submap]; floorIdx = mapping->floorIdx[submap];
hasFloor[i] = Floor_DecodeFrame(ctx, &ctx->floors[floorIdx], i); hasFloor[i] = Floor_DecodeFrame(ctx, &ctx->floors[floorIdx], i);
@ -1418,7 +1498,8 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
} }
/* non-zero vector propogate */ /* non-zero vector propogate */
for (i = 0; i < mapping->couplingSteps; i++) { for (i = 0; i < mapping->couplingSteps; i++)
{
magChannel = mapping->magnitude[i]; magChannel = mapping->magnitude[i];
angChannel = mapping->angle[i]; angChannel = mapping->angle[i];
@ -1428,10 +1509,12 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
} }
/* decode residue */ /* decode residue */
for (i = 0; i < mapping->submaps; i++) { for (i = 0; i < mapping->submaps; i++)
{
ch = 0; ch = 0;
/* map residue data to actual channel data */ /* map residue data to actual channel data */
for (j = 0; j < ctx->channels; j++) { for (j = 0; j < ctx->channels; j++)
{
if (mapping->mux[j] != i) continue; if (mapping->mux[j] != i) continue;
doNotDecode[ch] = !hasResidue[j]; doNotDecode[ch] = !hasResidue[j];
@ -1444,11 +1527,13 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
} }
/* inverse coupling */ /* inverse coupling */
for (i = mapping->couplingSteps - 1; i >= 0; i--) { for (i = mapping->couplingSteps - 1; i >= 0; i--)
{
magValues = ctx->curOutput[mapping->magnitude[i]]; magValues = ctx->curOutput[mapping->magnitude[i]];
angValues = ctx->curOutput[mapping->angle[i]]; angValues = ctx->curOutput[mapping->angle[i]];
for (j = 0; j < ctx->dataSize; j++) { for (j = 0; j < ctx->dataSize; j++)
{
m = magValues[j]; a = angValues[j]; m = magValues[j]; a = angValues[j];
if (m > 0.0f) { if (m > 0.0f) {
@ -1468,7 +1553,8 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
} }
/* compute dot product of floor and residue, producing audio spectrum vector */ /* compute dot product of floor and residue, producing audio spectrum vector */
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
if (!hasFloor[i]) continue; if (!hasFloor[i]) continue;
submap = mapping->mux[i]; submap = mapping->mux[i];
@ -1477,7 +1563,8 @@ cc_result Vorbis_DecodeFrame(struct VorbisState* ctx) {
} }
/* inverse monolithic transform of audio spectrum vector */ /* inverse monolithic transform of audio spectrum vector */
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
tmp = ctx->curOutput[i]; tmp = ctx->curOutput[i];
if (!hasFloor[i]) { if (!hasFloor[i]) {
@ -1528,14 +1615,17 @@ int Vorbis_OutputFrame(struct VorbisState* ctx, cc_int16* data) {
curOffset = curQrtr - overlapQtr; curOffset = curQrtr - overlapQtr;
prevOffset = prevQrtr - overlapQtr; prevOffset = prevQrtr - overlapQtr;
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
prev[i] = ctx->prevOutput[i] + (prevQrtr * 2); prev[i] = ctx->prevOutput[i] + (prevQrtr * 2);
cur[i] = ctx->curOutput[i]; cur[i] = ctx->curOutput[i];
} }
/* for long prev and short cur block, there will be non-overlapped data before */ /* for long prev and short cur block, there will be non-overlapped data before */
for (i = 0; i < prevOffset; i++) { for (i = 0; i < prevOffset; i++)
for (ch = 0; ch < ctx->channels; ch++) { {
for (ch = 0; ch < ctx->channels; ch++)
{
sample = prev[ch][i]; sample = prev[ch][i];
Math_Clamp(sample, -1.0f, 1.0f); Math_Clamp(sample, -1.0f, 1.0f);
*data++ = (cc_int16)(sample * 32767); *data++ = (cc_int16)(sample * 32767);
@ -1543,7 +1633,8 @@ int Vorbis_OutputFrame(struct VorbisState* ctx, cc_int16* data) {
} }
/* adjust pointers to start at 0 for overlapping */ /* adjust pointers to start at 0 for overlapping */
for (i = 0; i < ctx->channels; i++) { for (i = 0; i < ctx->channels; i++)
{
prev[i] += prevOffset; cur[i] += curOffset; prev[i] += prevOffset; cur[i] += curOffset;
} }
@ -1552,8 +1643,10 @@ int Vorbis_OutputFrame(struct VorbisState* ctx, cc_int16* data) {
/* overlap and add data */ /* overlap and add data */
/* also perform windowing here */ /* also perform windowing here */
for (i = 0; i < overlapSize; i++) { for (i = 0; i < overlapSize; i++)
for (ch = 0; ch < ctx->channels; ch++) { {
for (ch = 0; ch < ctx->channels; ch++)
{
sample = prev[ch][i] * window.Prev[i] + cur[ch][i] * window.Cur[i]; sample = prev[ch][i] * window.Prev[i] + cur[ch][i] * window.Cur[i];
Math_Clamp(sample, -1.0f, 1.0f); Math_Clamp(sample, -1.0f, 1.0f);
*data++ = (cc_int16)(sample * 32767); *data++ = (cc_int16)(sample * 32767);
@ -1562,8 +1655,10 @@ int Vorbis_OutputFrame(struct VorbisState* ctx, cc_int16* data) {
/* for long cur and short prev block, there will be non-overlapped data after */ /* for long cur and short prev block, there will be non-overlapped data after */
for (i = 0; i < ctx->channels; i++) { cur[i] += overlapSize; } for (i = 0; i < ctx->channels; i++) { cur[i] += overlapSize; }
for (i = 0; i < curOffset; i++) { for (i = 0; i < curOffset; i++)
for (ch = 0; ch < ctx->channels; ch++) { {
for (ch = 0; ch < ctx->channels; ch++)
{
sample = cur[ch][i]; sample = cur[ch][i];
Math_Clamp(sample, -1.0f, 1.0f); Math_Clamp(sample, -1.0f, 1.0f);
*data++ = (cc_int16)(sample * 32767); *data++ = (cc_int16)(sample * 32767);