diff --git a/src/Client/Audio.c b/src/Client/Audio.c index 3e901dc3b..688e82067 100644 --- a/src/Client/Audio.c +++ b/src/Client/Audio.c @@ -639,9 +639,9 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, Real32* da if (!Step2[i]) continue; hx = f->XList[i]; hy = YFinal[i] * f->Multiplier; - if (lx >= ctx->DataSize) return; - - render_line(lx, ly, min(hx, ctx->DataSize), hy, data); + if (lx < hx) { + render_line(lx, ly, min(hx, ctx->DataSize), hy, data); + } lx = hx; ly = hy; } @@ -704,7 +704,12 @@ static void Residue_DecodeCore(struct VorbisState* ctx, struct Residue* r, UInt3 UInt32 classwordsPerCodeword = classbook->Dimensions; UInt32 nToRead = residueEnd - residueBeg; UInt32 partitionsToRead = nToRead / r->PartitionSize; + + UInt8* classifications_raw = Platform_MemAlloc(ch * partitionsToRead * classbook->Dimensions, sizeof(UInt8), "temp classicifcations"); UInt8* classifications[VORBIS_MAX_CHANS]; /* TODO ????? */ + for (i = 0; i < ch; i++) { + classifications[i] = classifications_raw + (i * partitionsToRead * classbook->Dimensions); + } if (nToRead == 0) return; for (pass = 0; pass < 8; pass++) { @@ -991,6 +996,21 @@ ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx) { /*########################################################################################################################* *-----------------------------------------------------Vorbis frame--------------------------------------------------------* *#########################################################################################################################*/ +#define PI MATH_PI +Real32* imdct(Real32* v, Int32 N) { + Real32* y = Platform_MemAlloc(N * 2, sizeof(Real32), "temp imdct"); + Int32 i, k; + + for (i = 0; i < 2 * N; i++) { + Real64 sum = 0; + for (k = 0; k < N; k++) { + sum += v[k] * Math_Cos((PI / N) * (i + 0.5 + N * 0.5) * (k + 0.5)); + } + y[i] = (1.0 / N) * sum; + } + return y; +} + ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) { Int32 i, j, packetType = Vorbis_ReadBits(ctx, 1); if (packetType) return VORBIS_ERR_FRAME_TYPE; @@ -1081,8 +1101,59 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) { Floor_Synthesis(ctx, &ctx->Floors[floorIdx], data); } - /* inverse monolithic transform of audio spectrum vector */ + Int32 n = ctx->CurBlockSize; + Int32 window_center = n / 2; + Int32 left_window_beg, left_window_end, left_n; + Int32 right_window_beg, right_window_end, right_n; + if (mode->BlockSizeFlag && !prev_window) { + left_window_beg = n / 4 - ctx->BlockSizes[0] / 4; + left_window_end = n / 4 + ctx->BlockSizes[0] / 4; + left_n = ctx->BlockSizes[0] / 2; + } else { + left_window_beg = 0; + left_window_end = window_center; + left_n = n / 2; + } + + if (mode->BlockSizeFlag && !next_window) { + right_window_beg = (n*3) / 4 - ctx->BlockSizes[0] / 4; + right_window_end = (n*3) / 4 + ctx->BlockSizes[0] / 4; + right_n = ctx->BlockSizes[0] / 2; + } else { + right_window_beg = window_center; + right_window_end = n; + left_n = n / 2; + } + + Real32* window = Platform_MemAlloc(n, sizeof(Real32), "temp window"); + for (i = 0; i < left_window_beg; i++) window[i] = 0; + for (i = left_window_beg; i < left_window_end; i++) { + Real64 inner = Math_Sin((i - left_window_beg + 0.5) / left_n * (PI/2)); + window[i] = Math_Sin((PI/2) * inner * inner); + } + for (i = left_window_end; i < right_window_beg; i++) window[i] = 1; + for (i = right_window_beg; i < right_window_end; i++) { + Real64 inner = Math_Sin((i - right_window_beg + 0.5) / right_n * (PI/2) + (PI/2)); + window[i] = Math_Sin((PI/2) * inner * inner); + } + for (i = right_window_end; i < n; i++) window[i] = 0; + + /* inverse monolithic transform of audio spectrum vector */ + for (i = 0; i < ctx->Channels; i++) { + if (!hasFloor[i]) continue; + Int32 submap = mapping->Mux[i]; + Int32 floorIdx = mapping->FloorIdx[submap]; + + Real32* data = Vorbis_ChanData(ctx, i); + Real32* output = imdct(data, ctx->DataSize); + + /* apply windowing */ + for (j = 0; j < n; j++) { output[j] *= window[j]; } + ctx->CurOutput[i] = output; + } + + /* overlap and add data */ } static Real32 floor1_inverse_dB_table[256] = { diff --git a/src/Client/Audio.h b/src/Client/Audio.h index 7a538fd3f..5c35ef6b1 100644 --- a/src/Client/Audio.h +++ b/src/Client/Audio.h @@ -28,6 +28,7 @@ enum VORBIS_ERR { VORBIS_ERR_FRAME_TYPE, }; +#define VORBIS_MAX_CHANS 8 struct Codebook; struct Floor; struct Residue; struct Mapping; struct Mode; struct VorbisState { UInt32 Bits; /* Holds bits across byte boundaries*/ @@ -38,6 +39,8 @@ struct VorbisState { UInt16 CurBlockSize, DataSize; Int32 SampleRate; Int32 BlockSizes[2]; Real32* Values; + Real32* PrevOutput[VORBIS_MAX_CHANS]; + Real32* CurOutput[VORBIS_MAX_CHANS]; struct Codebook* Codebooks; struct Floor* Floors; diff --git a/src/Client/IModel.h b/src/Client/IModel.h index 299b3ca15..69db47eaa 100644 --- a/src/Client/IModel.h +++ b/src/Client/IModel.h @@ -35,7 +35,6 @@ struct IModel { /* Index within ModelCache's textures of the default texture for this model. */ Int8 defaultTexIndex; - /* Whether the vertices of this model have actually been filled. */ bool initalised; /* Whether the entity should be slightly bobbed up and down when rendering. e.g. for players when their legs are at the peak of their swing, the whole model will be moved slightly down. */ diff --git a/src/Client/Program.c b/src/Client/Program.c index f419d62ea..ca8520b48 100644 --- a/src/Client/Program.c +++ b/src/Client/Program.c @@ -29,7 +29,9 @@ int main(void) { struct VorbisState state; Vorbis_Init(&state, &ogg); Vorbis_DecodeHeaders(&state); - Vorbis_DecodeFrame(&state); + for (int i = 0; i < 1000; i++) { + Vorbis_DecodeFrame(&state); + } /*Platform_HttpInit(); AsyncRequest req = { 0 };