fix tab list sometimes updating names when don't need to

This commit is contained in:
UnknownShadow200 2018-11-17 14:02:56 +11:00
parent 511f981853
commit 5ce3007443
5 changed files with 218 additions and 153 deletions

View File

@ -834,7 +834,7 @@ static void Collisions_CollideWithReachableBlocks(struct CollisionsComp* comp, i
/* Unpack the block and coordinate data */
state = Searcher_States[i];
bPos.X = state.X >> 3; bPos.Y = state.Y >> 4; bPos.Z = state.Z >> 3;
int block = (state.X & 0x7) | (state.Y & 0xF) << 3 | (state.Z & 0x7) << 7;
block = (state.X & 0x7) | (state.Y & 0xF) << 3 | (state.Z & 0x7) << 7;
Vector3_Add(&blockBB.Min, &Block_MinBB[block], &bPos);
Vector3_Add(&blockBB.Max, &Block_MaxBB[block], &bPos);

View File

@ -462,19 +462,21 @@ bool Window_GetPendingEvent(XEvent* e) {
void Window_ProcessEvents(void) {
XEvent e;
bool wasVisible, wasFocused;
while (Window_Exists) {
if (!Window_GetPendingEvent(&e)) break;
switch (e.type) {
case MapNotify:
case UnmapNotify:
{
bool wasVisible = win_visible;
wasVisible = win_visible;
win_visible = e.type == MapNotify;
if (win_visible != wasVisible) {
Event_RaiseVoid(&WindowEvents_VisibilityChanged);
}
} break;
break;
case ClientMessage:
if (!win_isExiting && e.xclient.data.l[0] == wm_destroy) {
@ -545,16 +547,15 @@ void Window_ProcessEvents(void) {
case FocusIn:
case FocusOut:
{
/* Don't lose focus when another app grabs key or mouse */
if (e.xfocus.mode == NotifyGrab || e.xfocus.mode == NotifyUngrab) break;
bool wasFocused = Window_Focused;
wasFocused = Window_Focused;
Window_Focused = e.type == FocusIn;
if (Window_Focused != wasFocused) {
Event_RaiseVoid(&WindowEvents_FocusChanged);
}
} break;
break;
case MappingNotify:
if (e.xmapping.request == MappingModifier || e.xmapping.request == MappingKeyboard) {

View File

@ -108,14 +108,18 @@ static void Handlers_RemoveEndPlus(String* value) {
}
static void Handlers_AddTablistEntry(EntityID id, const String* playerName, const String* listName, const String* groupName, uint8_t groupRank) {
String oldPlayerName, oldListName, oldGroupName;
uint8_t oldGroupRank;
bool changed;
/* Only redraw the tab list if something changed. */
if (TabList_Valid(id)) {
String oldPlayerName = TabList_UNSAFE_GetPlayer(id);
String oldListName = TabList_UNSAFE_GetList(id);
String oldGroupName = TabList_UNSAFE_GetList(id);
uint8_t oldGroupRank = TabList_GroupRanks[id];
oldPlayerName = TabList_UNSAFE_GetPlayer(id);
oldListName = TabList_UNSAFE_GetList(id);
oldGroupName = TabList_UNSAFE_GetGroup(id);
oldGroupRank = TabList_GroupRanks[id];
bool changed = !String_Equals(playerName, &oldPlayerName) || !String_Equals(listName, &oldListName)
changed = !String_Equals(playerName, &oldPlayerName) || !String_Equals(listName, &oldListName)
|| !String_Equals(groupName, &oldGroupName) || groupRank != oldGroupRank;
if (changed) {
TabList_Set(id, playerName, listName, groupName, groupRank);

View File

@ -483,6 +483,7 @@ void TexturePack_ExtractDefault(void) {
void TexturePack_ExtractCurrent(const String* url) {
static String zipExt = String_FromConst(".zip");
struct Stream stream;
bool zip;
ReturnCode res = 0;
if (!url->length) { TexturePack_ExtractDefault(); return; }
@ -491,15 +492,13 @@ void TexturePack_ExtractCurrent(const String* url) {
/* e.g. 404 errors */
if (World_TextureUrl.length) TexturePack_ExtractDefault();
} else {
if (String_Equals(url, &World_TextureUrl)) {
} else {
bool zip = String_ContainsString(url, &zipExt);
if (!String_Equals(url, &World_TextureUrl)) {
zip = String_ContainsString(url, &zipExt);
String_Copy(&World_TextureUrl, url);
const char* operation = zip ? "extracting" : "decoding";
res = zip ? TexturePack_ExtractZip(&stream) :
TexturePack_ExtractTerrainPng(&stream);
if (res) { Chat_LogError2(res, operation, url); }
if (res) Chat_LogError2(res, zip ? "extracting" : "decoding", url);
}
res = stream.Close(&stream);
@ -508,22 +507,27 @@ void TexturePack_ExtractCurrent(const String* url) {
}
void TexturePack_Extract_Req(struct AsyncRequest* item) {
String url = String_FromRawArray(item->URL);
String_Copy(&World_TextureUrl, &url);
void* data = item->ResultData;
uint32_t len = item->ResultSize;
String url, etag;
void* data; uint32_t len;
struct Stream mem;
bool png;
ReturnCode res;
String etag = String_FromRawArray(item->Etag);
url = String_FromRawArray(item->URL);
String_Copy(&World_TextureUrl, &url);
data = item->ResultData;
len = item->ResultSize;
etag = String_FromRawArray(item->Etag);
TextureCache_Set(&url, data, len);
TextureCache_SetETag(&url, &etag);
TextureCache_SetLastModified(&url, &item->LastModified);
struct Stream mem; Stream_ReadonlyMemory(&mem, data, len);
bool png = Png_Detect(data, len);
ReturnCode res = png ? TexturePack_ExtractTerrainPng(&mem)
Stream_ReadonlyMemory(&mem, data, len);
png = Png_Detect(data, len);
res = png ? TexturePack_ExtractTerrainPng(&mem)
: TexturePack_ExtractZip(&mem);
const char* operation = png ? "decoding" : "extracting";
if (res) { Chat_LogError2(res, operation, &url); }
if (res) Chat_LogError2(res, png ? "decoding" : "extracting", &url);
ASyncRequest_Free(item);
}

View File

@ -14,31 +14,40 @@
#define OGG_FourCC(a, b, c, d) (((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | (uint32_t)d)
static ReturnCode Ogg_NextPage(struct Stream* stream) {
uint8_t header[27];
struct Stream* source = stream->Meta.Ogg.Source;
struct Stream* source;
uint32_t sig, size;
int i, numSegments;
uint8_t segments[255];
ReturnCode res;
/* OGG page format:
* header[0] (4) page signature
* header[4] (1) page version
* header[5] (1) page flags
* header[6] (8) granule position
* header[14] (4) serial number
* header[18] (4) page sequence number
* header[22] (4) page checksum
* header[26] (1) number of segments
* [number of segments] number of bytes in each segment
* [sum of bytes in each segment] page data
*/
source = stream->Meta.Ogg.Source;
if ((res = Stream_Read(source, header, sizeof(header)))) return res;
uint32_t sig = Stream_GetU32_BE(&header[0]);
sig = Stream_GetU32_BE(&header[0]);
if (sig != OGG_FourCC('O','g','g','S')) return OGG_ERR_INVALID_SIG;
if (header[4] != 0) return OGG_ERR_VERSION;
uint8_t bitflags = header[5];
/* header[6] (8) granule position */
/* header[14] (4) serial number */
/* header[18] (4) page sequence number */
/* header[22] (4) page checksum */
int i, numSegments = header[26];
uint8_t segments[255];
numSegments = header[26];
size = 0;
if ((res = Stream_Read(source, segments, numSegments))) return res;
for (i = 0; i < numSegments; i++) size += segments[i];
uint32_t dataSize = 0;
for (i = 0; i < numSegments; i++) { dataSize += segments[i]; }
if ((res = Stream_Read(source, stream->Meta.Ogg.Base, dataSize))) return res;
if ((res = Stream_Read(source, stream->Meta.Ogg.Base, size))) return res;
stream->Meta.Ogg.Cur = stream->Meta.Ogg.Base;
stream->Meta.Ogg.Left = dataSize;
stream->Meta.Ogg.Last = bitflags & 4;
stream->Meta.Ogg.Left = size;
stream->Meta.Ogg.Last = header[5] & 4;
return 0;
}
@ -91,7 +100,7 @@ void Ogg_MakeStream(struct Stream* stream, uint8_t* buffer, struct Stream* sourc
#define Vorbis_PeekBits(ctx, bits) (ctx->Bits & ((1UL << (bits)) - 1UL))
#define Vorbis_ConsumeBits(ctx, bits) ctx->Bits >>= (bits); ctx->NumBits -= (bits);
/* Aligns bit buffer to be on a byte boundary */
#define Vorbis_AlignBits(ctx) uint32_t alignSkip = ctx->NumBits & 7; Vorbis_ConsumeBits(ctx, alignSkip);
#define Vorbis_AlignBits(ctx) alignSkip = ctx->NumBits & 7; Vorbis_ConsumeBits(ctx, alignSkip);
/* TODO: Make sure this is inlined */
static uint32_t Vorbis_ReadBits(struct VorbisState* ctx, uint32_t bitsCount) {
@ -193,12 +202,12 @@ static uint32_t Codebook_Pow(uint32_t base, uint32_t exp) {
}
static uint32_t Codebook_Lookup1Values(uint32_t entries, uint32_t dimensions) {
uint32_t i;
uint32_t i, pow, next;
/* the greatest integer value for which [value] to the power of [dimensions] is less than or equal to [entries] */
/* TODO: verify this */
for (i = 1; ; i++) {
uint32_t pow = Codebook_Pow(i, dimensions);
uint32_t next = Codebook_Pow(i + 1, dimensions);
pow = Codebook_Pow(i, dimensions);
next = Codebook_Pow(i + 1, dimensions);
if (next < pow) return i; /* overflow */
if (pow == entries) return i;
@ -268,20 +277,28 @@ static bool Codebook_CalcCodewords(struct Codebook* c, uint8_t* len) {
}
static ReturnCode Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook* c) {
uint32_t sync = Vorbis_ReadBits(ctx, 24);
uint32_t sync;
uint8_t* codewordLens;
int i, entry;
int sparse, len;
int runBits, runLen;
int valueBits;
uint32_t lookupValues;
sync = Vorbis_ReadBits(ctx, 24);
if (sync != CODEBOOK_SYNC) return VORBIS_ERR_CODEBOOK_SYNC;
c->Dimensions = Vorbis_ReadBits(ctx, 16);
c->Entries = Vorbis_ReadBits(ctx, 24);
uint8_t* codewordLens = Mem_Alloc(c->Entries, 1, "raw codeword lens");
int i, ordered = Vorbis_ReadBit(ctx), usedEntries = 0;
codewordLens = Mem_Alloc(c->Entries, 1, "raw codeword lens");
for (i = 0; i < Array_Elems(c->NumCodewords); i++) {
c->NumCodewords[i] = 0;
}
if (!ordered) {
int sparse = Vorbis_ReadBit(ctx);
/* ordered entries flag */
if (!Vorbis_ReadBit(ctx)) {
sparse = Vorbis_ReadBit(ctx);
entry = 0;
for (i = 0; i < c->Entries; i++) {
/* sparse trees may not have all entries */
if (sparse && !Vorbis_ReadBit(ctx)){
@ -289,31 +306,27 @@ static ReturnCode Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
continue; /* unused entry */
}
int len = Vorbis_ReadBits(ctx, 5) + 1;
len = Vorbis_ReadBits(ctx, 5) + 1;
codewordLens[i] = len;
c->NumCodewords[len]++;
usedEntries++;
entry++;
}
} else {
int entry;
int curLength = Vorbis_ReadBits(ctx, 5) + 1;
for (entry = 0; entry < c->Entries;) {
int runBits = iLog(c->Entries - entry);
int runLen = Vorbis_ReadBits(ctx, runBits);
len = Vorbis_ReadBits(ctx, 5) + 1;
for (entry = 0; entry < c->Entries; entry += runLen) {
runBits = iLog(c->Entries - entry);
runLen = Vorbis_ReadBits(ctx, runBits);
for (i = entry; i < entry + runLen; i++) {
codewordLens[i] = curLength;
codewordLens[i] = len;
}
c->NumCodewords[curLength] = runLen;
entry += runLen;
curLength++;
c->NumCodewords[len++] = runLen;
if (entry > c->Entries) return VORBIS_ERR_CODEBOOK_ENTRY;
}
usedEntries = c->Entries;
entry = c->Entries;
}
c->TotalCodewords = usedEntries;
c->TotalCodewords = entry;
Codebook_CalcCodewords(c, codewordLens);
Mem_Free(codewordLens);
@ -324,10 +337,9 @@ static ReturnCode Codebook_DecodeSetup(struct VorbisState* ctx, struct Codebook*
c->MinValue = float32_unpack(ctx);
c->DeltaValue = float32_unpack(ctx);
int valueBits = Vorbis_ReadBits(ctx, 4) + 1;
valueBits = Vorbis_ReadBits(ctx, 4) + 1;
c->SequenceP = Vorbis_ReadBit(ctx);
uint32_t lookupValues;
if (c->LookupType == 1) {
lookupValues = Codebook_Lookup1Values(c->Entries, c->Dimensions);
} else {
@ -432,9 +444,13 @@ static void Floor_SortXList(int left, int right) {
}
static ReturnCode Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
f->Partitions = Vorbis_ReadBits(ctx, 5);
int i, j, idx, maxClass = -1;
static int16_t ranges[4] = { 256, 128, 84, 64 };
int i, j, idx, maxClass;
int rangeBits, classNum;
int16_t xlist_sorted[FLOOR_MAX_VALUES];
f->Partitions = Vorbis_ReadBits(ctx, 5);
maxClass = -1;
for (i = 0; i < f->Partitions; i++) {
f->PartitionClasses[i] = Vorbis_ReadBits(ctx, 4);
maxClass = max(maxClass, f->PartitionClasses[i]);
@ -443,24 +459,24 @@ static ReturnCode Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
for (i = 0; i <= maxClass; i++) {
f->ClassDimensions[i] = Vorbis_ReadBits(ctx, 3) + 1;
f->ClassSubClasses[i] = Vorbis_ReadBits(ctx, 2);
if (f->ClassSubClasses[i]) {
f->ClassMasterbooks[i] = Vorbis_ReadBits(ctx, 8);
}
for (j = 0; j < (1 << f->ClassSubClasses[i]); j++) {
f->SubclassBooks[i][j] = Vorbis_ReadBits(ctx, 8); f->SubclassBooks[i][j]--;
f->SubclassBooks[i][j] = (int16_t)Vorbis_ReadBits(ctx, 8) - 1;
}
}
f->Multiplier = Vorbis_ReadBits(ctx, 2) + 1;
static int16_t ranges[4] = { 256, 128, 84, 64 };
f->Range = ranges[f->Multiplier - 1];
rangeBits = Vorbis_ReadBits(ctx, 4);
int rangeBits = Vorbis_ReadBits(ctx, 4);
f->XList[0] = 0;
f->XList[1] = 1 << rangeBits;
for (i = 0, idx = 2; i < f->Partitions; i++) {
int classNum = f->PartitionClasses[i];
classNum = f->PartitionClasses[i];
for (j = 0; j < f->ClassDimensions[classNum]; j++) {
f->XList[idx++] = Vorbis_ReadBits(ctx, rangeBits);
}
@ -468,7 +484,6 @@ static ReturnCode Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
f->Values = idx;
/* sort X list for curve computation later */
int16_t xlist_sorted[FLOOR_MAX_VALUES];
Mem_Copy(xlist_sorted, f->XList, idx * 2);
for (i = 0; i < idx; i++) { f->ListOrder[i] = i; }
@ -479,29 +494,36 @@ static ReturnCode Floor_DecodeSetup(struct VorbisState* ctx, struct Floor* f) {
}
static bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, int ch) {
int nonZero = Vorbis_ReadBits(ctx, 1);
if (!nonZero) return false;
int32_t* yList = f->YList[ch];
int32_t* yList;
int i, j, idx, rangeBits;
uint8_t class, cdim, cbits;
int bookNum;
uint32_t csub, cval;
int i, j, idx, rangeBits = iLog(f->Range - 1);
/* does this frame have any energy */
if (!Vorbis_ReadBit(ctx)) return false;
yList = f->YList[ch];
rangeBits = iLog(f->Range - 1);
yList[0] = Vorbis_ReadBits(ctx, rangeBits);
yList[1] = Vorbis_ReadBits(ctx, rangeBits);
for (i = 0, idx = 2; i < f->Partitions; i++) {
uint8_t class = f->PartitionClasses[i];
uint8_t cdim = f->ClassDimensions[class];
uint8_t cbits = f->ClassSubClasses[class];
class = f->PartitionClasses[i];
cdim = f->ClassDimensions[class];
cbits = f->ClassSubClasses[class];
uint32_t csub = (1 << cbits) - 1;
uint32_t cval = 0;
csub = (1 << cbits) - 1;
cval = 0;
if (cbits) {
uint8_t bookNum = f->ClassMasterbooks[class];
bookNum = f->ClassMasterbooks[class];
cval = Codebook_DecodeScalar(ctx, &ctx->Codebooks[bookNum]);
}
for (j = 0; j < cdim; j++) {
int16_t bookNum = f->SubclassBooks[class][cval & csub];
bookNum = f->SubclassBooks[class][cval & csub];
cval >>= cbits;
if (bookNum >= 0) {
yList[idx + j] = Codebook_DecodeScalar(ctx, &ctx->Codebooks[bookNum]);
} else {
@ -800,16 +822,20 @@ struct Mapping {
};
static ReturnCode Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m) {
int i, submaps = 1;
int i, submaps, reserved;
int couplingSteps, couplingBits;
submaps = 1;
if (Vorbis_ReadBit(ctx)) {
submaps = Vorbis_ReadBits(ctx, 4) + 1;
}
int couplingSteps = 0;
couplingSteps = 0;
if (Vorbis_ReadBit(ctx)) {
couplingSteps = Vorbis_ReadBits(ctx, 8) + 1;
/* TODO: How big can couplingSteps ever really get in practice? */
int couplingBits = iLog(ctx->Channels - 1);
couplingBits = iLog(ctx->Channels - 1);
for (i = 0; i < couplingSteps; i++) {
m->Magnitude[i] = Vorbis_ReadBits(ctx, couplingBits);
m->Angle[i] = Vorbis_ReadBits(ctx, couplingBits);
@ -817,7 +843,7 @@ static ReturnCode Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m
}
}
int reserved = Vorbis_ReadBits(ctx, 2);
reserved = Vorbis_ReadBits(ctx, 2);
if (reserved != 0) return VORBIS_ERR_MAPPING_RESERVED;
m->Submaps = submaps;
m->CouplingSteps = couplingSteps;
@ -846,10 +872,11 @@ static ReturnCode Mapping_DecodeSetup(struct VorbisState* ctx, struct Mapping* m
*#########################################################################################################################*/
#define PI MATH_PI
void imdct_slow(float* in, float* out, int N) {
double sum;
int i, k;
for (i = 0; i < 2 * N; i++) {
double sum = 0;
sum = 0;
for (k = 0; k < N; k++) {
sum += in[k] * Math_Cos((PI / N) * (i + 0.5 + N * 0.5) * (k + 0.5));
}
@ -899,16 +926,19 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
float u[VORBIS_MAX_BLOCK_SIZE];
float w[VORBIS_MAX_BLOCK_SIZE];
float e_1, e_2, f_1, f_2;
float g_1, g_2, h_1, h_2;
float x_1, x_2, y_1, y_2;
/* spectral coefficients, step 1, step 2 */
for (k = 0, k2 = 0, k4 = 0; k < n8; k++, k2 += 2, k4 += 4) {
float e_1 = -in[k4+3], e_2 = -in[k4+1];
float g_1 = e_1 * A[n2-1-k2] + e_2 * A[n2-2-k2];
float g_2 = e_1 * A[n2-2-k2] - e_2 * A[n2-1-k2];
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_2 = e_1 * A[n2-2-k2] - e_2 * A[n2-1-k2];
float f_1 = in[n2-4-k4], f_2 = in[n2-2-k4];
float h_2 = f_1 * A[n4-2-k2] - f_2 * A[n4-1-k2];
float h_1 = f_1 * A[n4-1-k2] + f_2 * A[n4-2-k2];
f_1 = in[n2-4-k4]; f_2 = in[n2-2-k4];
h_2 = f_1 * A[n4-2-k2] - f_2 * A[n4-1-k2];
h_1 = f_1 * A[n4-1-k2] + f_2 * A[n4-2-k2];
w[n2+3+k4] = h_2 + g_2;
w[n2+1+k4] = h_1 + g_1;
@ -925,8 +955,8 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
for (r = 0, r4 = 0; r < rMax; r++, r4 += 4) {
for (s2 = 0; s2 < s2Max; s2 += 2) {
float e_1 = w[n-1-k0*s2-r4], e_2 = w[n-3-k0*s2-r4];
float f_1 = w[n-1-k0*(s2+1)-r4], f_2 = w[n-3-k0*(s2+1)-r4];
e_1 = w[n-1-k0*s2-r4]; e_2 = w[n-3-k0*s2-r4];
f_1 = w[n-1-k0*(s2+1)-r4]; f_2 = w[n-3-k0*(s2+1)-r4];
u[n-1-k0*s2-r4] = e_1 + f_1;
u[n-3-k0*s2-r4] = e_2 + f_2;
@ -947,23 +977,23 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
uint32_t* reversed = state->Reversed;
for (k = 0, k2 = 0, k8 = 0; k < n8; k++, k2 += 2, k8 += 8) {
uint32_t j = reversed[k], j8 = j << 3;
float e_1 = u[n-j8-1], e_2 = u[n-j8-3];
float f_1 = u[j8+3], f_2 = u[j8+1];
e_1 = u[n-j8-1]; e_2 = u[n-j8-3];
f_1 = u[j8+3]; f_2 = u[j8+1];
float g_1 = e_1 + f_1 + C[k2+1] * (e_1 - f_1) + C[k2] * (e_2 + f_2);
float h_1 = e_1 + f_1 - C[k2+1] * (e_1 - f_1) - C[k2] * (e_2 + f_2);
float g_2 = e_2 - f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
float h_2 = -e_2 + f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
g_1 = e_1 + f_1 + C[k2+1] * (e_1 - f_1) + C[k2] * (e_2 + f_2);
h_1 = e_1 + f_1 - C[k2+1] * (e_1 - f_1) - C[k2] * (e_2 + f_2);
g_2 = e_2 - f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
h_2 = -e_2 + f_2 + C[k2+1] * (e_2 + f_2) - C[k2] * (e_1 - f_1);
float x_1 = -0.5f * (g_1 * B[k2] + g_2 * B[k2+1]);
float x_2 = -0.5f * (g_1 * B[k2+1] - g_2 * B[k2]);
x_1 = -0.5f * (g_1 * B[k2] + g_2 * B[k2+1]);
x_2 = -0.5f * (g_1 * B[k2+1] - g_2 * B[k2]);
out[n4-1-k] = -x_2;
out[n4+k] = x_2;
out[n3_4-1-k] = x_1;
out[n3_4+k] = x_1;
float y_1 = -0.5f * (h_1 * B[n2-2-k2] + h_2 * B[n2-1-k2]);
float y_2 = -0.5f * (h_1 * B[n2-1-k2] - h_2 * B[n2-2-k2]);
y_1 = -0.5f * (h_1 * B[n2-2-k2] + h_2 * B[n2-1-k2]);
y_2 = -0.5f * (h_1 * B[n2-1-k2] - h_2 * B[n2-2-k2]);
out[k] = -y_2;
out[n2-1-k] = y_2;
out[n2+k] = y_1;
@ -977,12 +1007,14 @@ void imdct_calc(float* in, float* out, struct imdct_state* state) {
*#########################################################################################################################*/
struct Mode { uint8_t BlockSizeFlag, MappingIdx; };
static ReturnCode Mode_DecodeSetup(struct VorbisState* ctx, struct Mode* m) {
m->BlockSizeFlag = Vorbis_ReadBits(ctx, 1);
int windowType = Vorbis_ReadBits(ctx, 16);
if (windowType != 0) return VORBIS_ERR_MODE_WINDOW;
int windowType, transformType;
m->BlockSizeFlag = Vorbis_ReadBit(ctx);
int transformType = Vorbis_ReadBits(ctx, 16);
windowType = Vorbis_ReadBits(ctx, 16);
if (windowType != 0) return VORBIS_ERR_MODE_WINDOW;
transformType = Vorbis_ReadBits(ctx, 16);
if (transformType != 0) return VORBIS_ERR_MODE_TRANSFORM;
m->MappingIdx = Vorbis_ReadBits(ctx, 8);
return 0;
}
@ -1062,6 +1094,7 @@ static ReturnCode Vorbis_DecodeIdentifier(struct VorbisState* ctx) {
static ReturnCode Vorbis_DecodeComments(struct VorbisState* ctx) {
uint32_t i, len, comments;
uint8_t flag;
ReturnCode res;
struct Stream* stream = ctx->Source;
@ -1077,12 +1110,12 @@ static ReturnCode Vorbis_DecodeComments(struct VorbisState* ctx) {
}
/* check framing flag */
uint8_t flag;
if ((res = stream->ReadU8(stream, &flag))) return res;
return (flag & 1) ? 0 : VORBIS_ERR_FRAMING;
}
static ReturnCode Vorbis_DecodeSetup(struct VorbisState* ctx) {
uint32_t framing, alignSkip;
int i, count;
ReturnCode res;
@ -1135,7 +1168,7 @@ static ReturnCode Vorbis_DecodeSetup(struct VorbisState* ctx) {
}
ctx->ModeNumBits = iLog(count - 1); /* ilog([vorbis_mode_count]-1) bits */
uint8_t framing = Vorbis_ReadBits(ctx, 1);
framing = Vorbis_ReadBit(ctx);
Vorbis_AlignBits(ctx);
/* check framing flag */
return (framing & 1) ? 0 : VORBIS_ERR_FRAMING;
@ -1176,14 +1209,37 @@ ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx) {
*-----------------------------------------------------Vorbis frame--------------------------------------------------------*
*#########################################################################################################################*/
ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
int i, j, packetType;
ReturnCode res = Vorbis_TryReadBits(ctx, 1, &packetType);
/* frame header */
uint32_t packetType;
struct Mapping* mapping;
struct Mode* mode;
int modeIdx;
/* floor/residue */
bool hasFloor[VORBIS_MAX_CHANS], hasResidue[VORBIS_MAX_CHANS];
bool doNotDecode[VORBIS_MAX_CHANS];
float* data[VORBIS_MAX_CHANS];
int submap, floorIdx;
int ch, residueIdx;
/* inverse coupling */
int magChannel, angChannel;
float* magValues, m;
float* angValues, a;
/* misc variables */
float* tmp;
uint32_t alignSkip;
int i, j;
ReturnCode res;
res = Vorbis_TryReadBits(ctx, 1, &packetType);
if (res) return res;
if (packetType) return VORBIS_ERR_FRAME_TYPE;
int modeIdx = Vorbis_ReadBits(ctx, ctx->ModeNumBits);
struct Mode* mode = &ctx->Modes[modeIdx];
struct Mapping* mapping = &ctx->Mappings[mode->MappingIdx];
modeIdx = Vorbis_ReadBits(ctx, ctx->ModeNumBits);
mode = &ctx->Modes[modeIdx];
mapping = &ctx->Mappings[mode->MappingIdx];
/* decode window shape */
ctx->CurBlockSize = ctx->BlockSizes[mode->BlockSizeFlag];
@ -1192,7 +1248,7 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
if (mode->BlockSizeFlag) { Vorbis_ReadBits(ctx, 2); } /* TODO: do we just SkipBits here */
/* swap prev and cur outputs around */
float* 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);
for (i = 0; i < ctx->Channels; i++) {
@ -1201,18 +1257,17 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
}
/* decode floor */
bool hasFloor[VORBIS_MAX_CHANS], hasResidue[VORBIS_MAX_CHANS];
for (i = 0; i < ctx->Channels; i++) {
int submap = mapping->Mux[i];
int floorIdx = mapping->FloorIdx[submap];
submap = mapping->Mux[i];
floorIdx = mapping->FloorIdx[submap];
hasFloor[i] = Floor_DecodeFrame(ctx, &ctx->Floors[floorIdx], i);
hasResidue[i] = hasFloor[i];
}
/* non-zero vector propogate */
for (i = 0; i < mapping->CouplingSteps; i++) {
int magChannel = mapping->Magnitude[i];
int angChannel = mapping->Angle[i];
magChannel = mapping->Magnitude[i];
angChannel = mapping->Angle[i];
if (hasResidue[magChannel] || hasResidue[angChannel]) {
hasResidue[magChannel] = true; hasResidue[angChannel] = true;
@ -1221,9 +1276,8 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
/* decode residue */
for (i = 0; i < mapping->Submaps; i++) {
int ch = 0;
bool doNotDecode[VORBIS_MAX_CHANS];
float* data[VORBIS_MAX_CHANS]; /* map residue data to actual channel data */
ch = 0;
/* map residue data to actual channel data */
for (j = 0; j < ctx->Channels; j++) {
if (mapping->Mux[j] != i) continue;
@ -1232,17 +1286,17 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
ch++;
}
int residueIdx = mapping->FloorIdx[i];
residueIdx = mapping->FloorIdx[i];
Residue_DecodeFrame(ctx, &ctx->Residues[residueIdx], ch, doNotDecode, data);
}
/* inverse coupling */
for (i = mapping->CouplingSteps - 1; i >= 0; i--) {
float* magValues = ctx->CurOutput[mapping->Magnitude[i]];
float* angValues = ctx->CurOutput[mapping->Angle[i]];
magValues = ctx->CurOutput[mapping->Magnitude[i]];
angValues = ctx->CurOutput[mapping->Angle[i]];
for (j = 0; j < ctx->DataSize; j++) {
float m = magValues[j], a = angValues[j];
m = magValues[j]; a = angValues[j];
if (m > 0.0f) {
if (a > 0.0f) { angValues[j] = m - a; }
@ -1263,19 +1317,21 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
/* compute dot product of floor and residue, producing audio spectrum vector */
for (i = 0; i < ctx->Channels; i++) {
if (!hasFloor[i]) continue;
int submap = mapping->Mux[i];
int floorIdx = mapping->FloorIdx[submap];
submap = mapping->Mux[i];
floorIdx = mapping->FloorIdx[submap];
Floor_Synthesis(ctx, &ctx->Floors[floorIdx], i);
}
/* inverse monolithic transform of audio spectrum vector */
for (i = 0; i < ctx->Channels; i++) {
float* data = ctx->CurOutput[i];
tmp = ctx->CurOutput[i];
if (!hasFloor[i]) {
/* TODO: Do we actually need to zero data here (residue type 2 maybe) */
Mem_Set(data, 0, ctx->CurBlockSize * sizeof(float));
Mem_Set(tmp, 0, ctx->CurBlockSize * sizeof(float));
} else {
imdct_calc(data, data, &ctx->imdct[mode->BlockSizeFlag]);
imdct_calc(tmp, tmp, &ctx->imdct[mode->BlockSizeFlag]);
/* defer windowing until output */
}
}