mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -04:00
fix divide by zero in vorbis decode
This commit is contained in:
parent
0a4b510811
commit
6c45c8df9e
@ -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] = {
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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 };
|
||||
|
Loading…
x
Reference in New Issue
Block a user