simplify vorbis windowing

This commit is contained in:
UnknownShadow200 2018-08-23 18:17:18 +10:00
parent 5185d0bf2e
commit 84ae5b6205
29 changed files with 66 additions and 128 deletions

View File

@ -1,6 +1,6 @@
#ifndef CC_2DSTRUCTS_H
#define CC_2DSTRUCTS_H
#include "Typedefs.h"
#include "Core.h"
/* Represents simple structures useful for 2D operations.
Copyright 2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_ANIMS_H
#define CC_ANIMS_H
#include "Typedefs.h"
#include "Core.h"
/* Texture animations, and water and lava liquid animations.
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
Based off the incredible work from https://dl.dropboxusercontent.com/u/12694594/lava.txt

View File

@ -1,6 +1,6 @@
#ifndef CC_AUDIO_H
#define CC_AUDIO_H
#include "Typedefs.h"
#include "Core.h"
/* Manages playing sound and music.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_AXISLINESRENDERER_H
#define CC_AXISLINESRENDERER_H
#include "Typedefs.h"
#include "Core.h"
/* Renders 3 lines showing direction of each axis.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_BITMAP_H
#define CC_BITMAP_H
#include "Typedefs.h"
#include "Core.h"
/* Represents a 2D array of pixels.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_BLOCKPHYSICS_H
#define CC_BLOCKPHYSICS_H
#include "Typedefs.h"
#include "Core.h"
#include "BlockID.h"
/* Implements simple block physics.
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3

View File

@ -1,6 +1,6 @@
#ifndef CC_BUILDER_H
#define CC_BUILDER_H
#include "Typedefs.h"
#include "Core.h"
/* Converts a 16x16x16 chunk into a mesh of vertices.
NormalMeshBuilder:
Implements a simple chunk mesh builder, where each block face is a single colour.

View File

@ -2,7 +2,7 @@
#define CC_CHAT_H
#include "Constants.h"
#include "Utils.h"
#include "Typedefs.h"
#include "Core.h"
/* Manages sending and logging chat.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_CHUNKUPDATER_H
#define CC_CHUNKUPDATER_H
#include "Typedefs.h"
#include "Core.h"
#include "Constants.h"
/* Manages the process of building/deleting chunk meshes.
Also sorts chunks so nearest chunks are ordered first, and calculates chunk visibility.

View File

@ -197,7 +197,6 @@
<ClInclude Include="Camera.h" />
<ClInclude Include="Chat.h" />
<ClInclude Include="ChunkUpdater.h" />
<ClInclude Include="Compiler.h" />
<ClInclude Include="Constants.h" />
<ClInclude Include="Bitmap.h" />
<ClInclude Include="DisplayDevice.h" />
@ -247,7 +246,7 @@
<ClInclude Include="GraphicsCommon.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="String.h" />
<ClInclude Include="Typedefs.h" />
<ClInclude Include="Core.h" />
<ClInclude Include="Vectors.h" />
<ClInclude Include="VertexStructs.h" />
<ClInclude Include="Vorbis.h" />

View File

@ -144,12 +144,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Typedefs.h">
<Filter>Header Files\Defines</Filter>
</ClInclude>
<ClInclude Include="Compiler.h">
<Filter>Header Files\Defines</Filter>
</ClInclude>
<ClInclude Include="Platform.h">
<Filter>Header Files\Platform</Filter>
</ClInclude>
@ -345,6 +339,9 @@
<ClInclude Include="Errors.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="Core.h">
<Filter>Header Files\Defines</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="String.c">

View File

@ -1,25 +0,0 @@
#ifndef CC_COMPILER_H
#define CC_COMPILER_H
#include "Typedefs.h"
/* Compiler-specific attributes and helpers
Copyright 2017 ClassicalSharp | Licensed under BSD-3
*/
#define HINT_INLINE inline
/* The following ifdef block is the standard way of creating macros which make exporting
from a DLL simpler. All files within this DLL are compiled with the CLIENT_EXPORTS
symbol defined on the command line. This symbol should not be defined on any project
that uses this DLL. This way any other project whose source files include this file see
CLIENT_API functions as being imported from a DLL, whereas this DLL sees symbols
defined with this macro as being exported.*/
#ifdef CLIENT_EXPORTS
#define CLIENT_FUNC __declspec(dllexport)
#else
#define CLIENT_FUNC __declspec(dllimport)
#endif
#define EXPORT_FUNC __declspec(dllexport)
#define IMPORT_FUNC __declspec(dllimport)
#endif

View File

@ -14,7 +14,8 @@ typedef signed __int8 Int8;
typedef signed __int16 Int16;
typedef signed __int32 Int32;
typedef signed __int64 Int64;
#elif __GNUC__ || (__STDC_VERSION__ >= 199901L)
#define FUNC_ATTRIB(args) __declspec(args)
#elif __GNUC__
#include <stdint.h>
typedef uint8_t UInt8;
typedef uint16_t UInt16;
@ -25,8 +26,9 @@ typedef int8_t Int8;
typedef int16_t Int16;
typedef int32_t Int32;
typedef int64_t Int64;
#define FUNC_ATTRIB(args) __attribute__((args))
#else
#error "I didn't add typedefs for this compiler. You'll need to define them in Typedefs.h!"
#error "I don't recognise this compiler. You'll need to add required definitions in Core.h!
#endif
typedef unsigned char UChar;

View File

@ -1,6 +1,6 @@
#ifndef CC_DEFLATE_H
#define CC_DEFLATE_H
#include "Typedefs.h"
#include "Core.h"
/* Decodes data compressed using DEFLATE in a streaming manner.
Partially based off information from
https://handmade.network/forums/wip/t/2363-implementing_a_basic_png_reader_the_handmade_way

View File

@ -1,6 +1,6 @@
#ifndef CC_DISPLAYDEVICE_H
#define CC_DISPLAYDEVICE_H
#include "Typedefs.h"
#include "Core.h"
#include "2DStructs.h"
/* Contains structs related to monitor displays.
Copyright 2017 ClassicalSharp | Licensed under BSD-3 | Based originally on OpenTK

View File

@ -1,6 +1,6 @@
#ifndef CC_ENVRENDERER_H
#define CC_ENVRENDERER_H
#include "Typedefs.h"
#include "Core.h"
/* Renders environment of the map. (clouds, sky, fog, map sides/edges, skybox, rain/snow)
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_MATH_H
#define CC_MATH_H
#include "Typedefs.h"
#include "Core.h"
/* Simple math functions and constants. Also implements a RNG algorithm, based on
Java's implementation from https://docs.oracle.com/javase/7/docs/api/java/util/Random.html
Copyright 2017 ClassicalSharp | Licensed under BSD-3

View File

@ -1,6 +1,6 @@
#ifndef CC_FUNCS_H
#define CC_FUNCS_H
#include "Typedefs.h"
#include "Core.h"
/* Simple function implementations
NOTE: doing min(x++, y) etc will increment x twice!
Copyright 2017 ClassicalSharp | Licensed under BSD-3

View File

@ -1,6 +1,6 @@
#ifndef CC_GAMESTRUCTS_H
#define CC_GAMESTRUCTS_H
#include "Typedefs.h"
#include "Core.h"
/* Represents Game related structures.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_HELDBLOCKRENDERER_H
#define CC_HELDBLOCKRENDERER_H
#include "Typedefs.h"
#include "Core.h"
/* Implements rendering of held block/arm at bottom right of game.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -1,6 +1,6 @@
#ifndef CC_INVENTORY_H
#define CC_INVENTORY_H
#include "Typedefs.h"
#include "Core.h"
#include "BlockID.h"
/* Manages inventory hotbar, and ordering of blocks in the inventory menu.

View File

@ -1,6 +1,6 @@
#ifndef CC_PICKEDPOSRENDERER_H
#define CC_PICKEDPOSRENDERER_H
#include "Typedefs.h"
#include "Core.h"
/* Renders an outline around the block the player is looking at.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/

View File

@ -117,7 +117,7 @@ ReturnCode Http_FreeRequest(void* handle);
ReturnCode Http_Free(void);
#define AUDIO_MAX_CHUNKS 4
struct AudioFormat { UInt16 Channels, BitsPerSample; Int32 SampleRate; };
struct AudioFormat { UInt8 Channels, BitsPerSample; Int32 SampleRate; };
#define AudioFormat_Eq(a, b) ((a)->Channels == (b)->Channels && (a)->BitsPerSample == (b)->BitsPerSample && (a)->SampleRate == (b)->SampleRate)
typedef Int32 AudioHandle;
@ -125,6 +125,7 @@ void Audio_Init(AudioHandle* handle, Int32 buffers);
void Audio_Free(AudioHandle handle);
struct AudioFormat* Audio_GetFormat(AudioHandle handle);
void Audio_SetFormat(AudioHandle handle, struct AudioFormat* format);
void Audio_SetVolume(AudioHandle handle, Real32 volume);
void Audio_PlayData(AudioHandle handle, Int32 idx, void* data, UInt32 dataSize);
bool Audio_IsCompleted(AudioHandle handle, Int32 idx);
bool Audio_IsFinished(AudioHandle handle);

View File

@ -1,4 +1,4 @@
#include "Typedefs.h"
#include "Core.h"
#include "ErrorHandler.h"
#include "Platform.h"
#include "Window.h"

View File

@ -1,6 +1,6 @@
#ifndef CC_STRING_H
#define CC_STRING_H
#include "Typedefs.h"
#include "Core.h"
/* Implements operations for a string.
Also implements conversions betweens strings and numbers.
Also implements converting code page 437 indices to/from unicode.

View File

@ -1,6 +1,6 @@
#ifndef CC_VECTORS_H
#define CC_VECTORS_H
#include "Typedefs.h"
#include "Core.h"
/* Represents 2, 3 dimensional vectors, and 4 x 4 matrix.
Frustum culling sourced from http://www.crownandcutlass.com/features/technicaldetails/frustum.html
Copyright 2017 ClassicalSharp | Licensed under BSD-3

View File

@ -475,7 +475,7 @@ static bool Floor_DecodeFrame(struct VorbisState* ctx, struct Floor* f, Int32 ch
return true;
}
static Int32 render_point(Int32 x0, Int32 y0, Int32 x1, Int32 y1, Int32 X) {
static Int32 Floor_RenderPoint(Int32 x0, Int32 y0, Int32 x1, Int32 y1, Int32 X) {
Int32 dy = y1 - y0, adx = x1 - x0;
Int32 ady = Math_AbsI(dy);
Int32 err = ady * (X - x0);
@ -489,7 +489,7 @@ static Int32 render_point(Int32 x0, Int32 y0, Int32 x1, Int32 y1, Int32 X) {
}
static Real32 floor1_inverse_dB_table[256];
static void render_line(Int32 x0, Int32 y0, Int32 x1, Int32 y1, Real32* data) {
static void Floor_RenderLine(Int32 x0, Int32 y0, Int32 x1, Int32 y1, Real32* data) {
Int32 dy = y1 - y0, adx = x1 - x0;
Int32 ady = Math_AbsI(dy);
Int32 base = dy / adx, sy;
@ -550,8 +550,8 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, Int32 ch)
Int32 lo_offset = low_neighbor(f->XList, i);
Int32 hi_offset = high_neighbor(f->XList, i);
Int32 predicted = render_point(f->XList[lo_offset], YFinal[lo_offset],
f->XList[hi_offset], YFinal[hi_offset], f->XList[i]);
Int32 predicted = Floor_RenderPoint(f->XList[lo_offset], YFinal[lo_offset],
f->XList[hi_offset], YFinal[hi_offset], f->XList[i]);
Int32 val = yList[i];
Int32 highroom = f->Range - predicted;
@ -582,7 +582,7 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, Int32 ch)
}
}
} else {
Step2[i] = false;
Step2[i] = false;
YFinal[i] = predicted;
}
}
@ -597,7 +597,7 @@ static void Floor_Synthesis(struct VorbisState* ctx, struct Floor* f, Int32 ch)
hx = f->XList[i]; hy = YFinal[i] * f->Multiplier;
if (lx < hx) {
render_line(lx, ly, min(hx, ctx->DataSize), hy, data);
Floor_RenderLine(lx, ly, min(hx, ctx->DataSize), hy, data);
}
lx = hx; ly = hy;
}
@ -949,45 +949,20 @@ static ReturnCode Mode_DecodeSetup(struct VorbisState* ctx, struct Mode* m) {
return 0;
}
static void Vorbis_CalcWindow(struct VorbisState* ctx, UInt32* offset, bool longBlock, bool prevLong, bool nextLong) {
Int32 i, n = ctx->BlockSizes[longBlock];
Int32 window_center = n / 2;
Int32 left_window_beg, left_window_end, left_n;
Int32 right_window_beg, right_window_end, right_n;
static void Vorbis_CalcWindow(struct VorbisWindow* window, Int32 blockSize) {
Int32 i, n = blockSize / 2;
window->Cur = window->Prev + n;
Real32* cur_window = window->Cur;
Real32* prev_window = window->Prev;
if (longBlock && !prevLong) {
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;
for (i = 0; i < n; i++) {
Real64 inner = Math_Sin((i + 0.5) / n * (PI/2));
cur_window[i] = Math_Sin((PI/2) * inner * inner);
}
if (longBlock && !nextLong) {
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;
right_n = n / 2;
for (i = 0; i < n; i++) {
Real64 inner = Math_Sin((i + 0.5) / n * (PI/2) + (PI/2));
prev_window[i] = Math_Sin((PI/2) * inner * inner);
}
Real32* window = ctx->WindowShort + *offset; (*offset) += n;
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;
}
void Vorbis_Free(struct VorbisState* ctx) {
@ -1001,11 +976,8 @@ void Vorbis_Free(struct VorbisState* ctx) {
Mem_Free(&ctx->Residues);
Mem_Free(&ctx->Mappings);
Mem_Free(&ctx->Modes);
Mem_Free(&ctx->WindowShort);
Mem_Free(&ctx->WindowRaw);
Mem_Free(&ctx->Temp);
ctx->Values[0] = NULL;
ctx->Values[1] = NULL;
}
static bool Vorbis_ValidBlockSize(UInt32 size) {
@ -1130,6 +1102,7 @@ static ReturnCode Vorbis_DecodeSetup(struct VorbisState* ctx) {
ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx) {
ReturnCode res;
UInt32 count;
if (res = Vorbis_CheckHeader(ctx, 1)) return res;
if (res = Vorbis_DecodeIdentifier(ctx)) return res;
@ -1139,18 +1112,13 @@ ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx) {
if (res = Vorbis_DecodeSetup(ctx)) return res;
/* window calculations can be pre-computed here */
UInt32 count = ctx->BlockSizes[0] + ctx->BlockSizes[1] * 4, offset = 0;
ctx->WindowShort = Mem_Alloc(count, sizeof(Real32), "Vorbis windows");
Vorbis_CalcWindow(ctx, &offset, false, false, false);
count = ctx->BlockSizes[0] + ctx->BlockSizes[1];
ctx->WindowRaw = Mem_Alloc(count, sizeof(Real32), "Vorbis windows");
ctx->Windows[0].Prev = ctx->WindowRaw;
ctx->Windows[1].Prev = ctx->WindowRaw + ctx->BlockSizes[0];
ctx->WindowLong[0][0] = ctx->WindowShort + offset;
Vorbis_CalcWindow(ctx, &offset, true, false, false);
ctx->WindowLong[1][0] = ctx->WindowShort + offset;
Vorbis_CalcWindow(ctx, &offset, true, false, true);
ctx->WindowLong[0][1] = ctx->WindowShort + offset;
Vorbis_CalcWindow(ctx, &offset, true, true, false);
ctx->WindowLong[1][1] = ctx->WindowShort + offset;
Vorbis_CalcWindow(ctx, &offset, true, true, true);
Vorbis_CalcWindow(&ctx->Windows[0], ctx->BlockSizes[0]);
Vorbis_CalcWindow(&ctx->Windows[1], ctx->BlockSizes[1]);
count = ctx->Channels * ctx->BlockSizes[1];
ctx->Temp = Mem_AllocCleared(count * 3, sizeof(Real32), "Vorbis values");
@ -1263,14 +1231,6 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
Floor_Synthesis(ctx, &ctx->Floors[floorIdx], i);
}
Int32 n = ctx->CurBlockSize;
Real32* window;
if (mode->BlockSizeFlag) {
window = ctx->WindowLong[prev_window][next_window];
} else {
window = ctx->WindowShort;
}
/* inverse monolithic transform of audio spectrum vector */
for (i = 0; i < ctx->Channels; i++) {
Real32* data = ctx->CurOutput[i];
@ -1279,7 +1239,7 @@ ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx) {
Mem_Set(data, 0, ctx->CurBlockSize * sizeof(Real32));
} else {
imdct_calc(data, data, &ctx->imdct[mode->BlockSizeFlag]);
for (j = 0; j < n; j++) { data[j] *= window[j]; }
/* defer windowing until output */
}
}
@ -1332,12 +1292,15 @@ Int32 Vorbis_OutputFrame(struct VorbisState* ctx, Int16* data) {
for (i = 0; i < ctx->Channels; i++) {
prev[i] += prevOffset; cur[i] += curOffset;
}
Int32 overlapSize = overlapQtr * 2;
struct VorbisWindow window = ctx->Windows[(overlapQtr * 4) == ctx->BlockSizes[1]];
/* overlap and add data */
/* also perform windowing here */
for (i = 0; i < overlapSize; i++) {
for (ch = 0; ch < ctx->Channels; ch++) {
Real32 sample = prev[ch][i] + cur[ch][i];
Real32 sample = prev[ch][i] * window.Prev[i] + cur[ch][i] * window.Cur[i];
Math_Clamp(sample, -1.0f, 1.0f);
*data++ = (Int16)(sample * 32767);
}

View File

@ -1,6 +1,6 @@
#ifndef CC_VORBIS_H
#define CC_VORBIS_H
#include "Typedefs.h"
#include "Core.h"
/* Decodes ogg vorbis audio
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
@ -21,6 +21,7 @@ struct imdct_state {
UInt32 Reversed[VORBIS_MAX_BLOCK_SIZE / 8];
};
struct VorbisWindow { Real32* Prev; Real32* Cur; };
struct VorbisState {
UInt32 Bits; /* Holds bits across byte boundaries*/
UInt32 NumBits; /* Number of bits in Bits buffer*/
@ -40,8 +41,8 @@ struct VorbisState {
struct Mapping* Mappings;
struct Mode* Modes;
Real32* WindowShort;
Real32* WindowLong[2][2];
Real32* WindowRaw;
struct VorbisWindow Windows[2];
struct imdct_state imdct[2];
};

View File

@ -534,7 +534,7 @@ void Window_SetVisible(bool visible) {
void Window_Close(void) {
PostMessageW(win_Handle, WM_CLOSE, NULL, NULL);
PostMessageW(win_Handle, WM_CLOSE, 0, 0);
}
UInt8 Window_GetWindowState(void) { return win_State; }