start porting audio to C client

This commit is contained in:
UnknownShadow200 2018-08-05 20:39:30 +10:00
parent 0d75633ec0
commit daaa68cea2
9 changed files with 1839 additions and 1296 deletions

View File

@ -16,8 +16,6 @@ namespace ClassicalSharp.Audio {
}
public class Soundboard {
public byte[] Data;
List<SoundGroup> groups = new List<SoundGroup>();
Random rnd = new Random();

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,6 @@
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
struct IGameComponent;
struct Stream;
void Audio_MakeComponent(struct IGameComponent* comp);
void Audio_SetMusic(Int32 volume);
@ -13,43 +12,4 @@ void Audio_SetSounds(Int32 volume);
void Audio_PlayDigSound(UInt8 type);
void Audio_PlayStepSound(UInt8 type);
enum OGG_VER { OGG_ERR_INVALID_SIG = 2552401, OGG_ERR_VERSION };
#define OGG_BUFFER_SIZE (255 * 256)
void Ogg_MakeStream(struct Stream* stream, UInt8* buffer, struct Stream* source);
enum VORBIS_ERR {
VORBIS_ERR_HEADER = 5238001, VORBIS_ERR_WRONG_HEADER, VORBIS_ERR_FRAMING,
VORBIS_ERR_VERSION, VORBIS_ERR_BLOCKSIZE, VORBIS_ERR_CHANS,
VORBIS_ERR_TIME_TYPE, VORBIS_ERR_FLOOR_TYPE, VORBIS_ERR_RESIDUE_TYPE,
VORBIS_ERR_MAPPING_TYPE, VORBIS_ERR_MODE_TYPE,
VORBIS_ERR_CODEBOOK_SYNC, VORBIS_ERR_CODEBOOK_ENTRY, VORBIS_ERR_CODEBOOK_LOOKUP,
VORBIS_ERR_MODE_WINDOW, VORBIS_ERR_MODE_TRANSFORM,
VORBIS_ERR_MAPPING_CHANS, VORBIS_ERR_MAPPING_RESERVED,
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*/
UInt32 NumBits; /* Number of bits in Bits buffer*/
struct Stream* Source; /* Source for filling Input buffer */
UInt8 Channels, ModeNumBits;
UInt16 CurBlockSize, PrevBlockSize, DataSize;
Int32 SampleRate; Int32 BlockSizes[2];
Real32* Values;
Real32* PrevOutput[VORBIS_MAX_CHANS];
Real32* CurOutput[VORBIS_MAX_CHANS];
struct Codebook* Codebooks;
struct Floor* Floors;
struct Residue* Residues;
struct Mapping* Mappings;
struct Mode* Modes;
};
void Vorbis_Init(struct VorbisState* ctx, struct Stream* source);
ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx);
ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx);
Int32 Vorbis_OutputFrame(struct VorbisState* ctx, Int16* data);
#endif

View File

@ -99,7 +99,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<EntryPointSymbol>main</EntryPointSymbol>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;dbghelp.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -119,7 +119,7 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>main</EntryPointSymbol>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;dbghelp.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;ucrtd.lib;vcruntimed.lib;msvcrtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -148,7 +148,7 @@
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<EntryPointSymbol>main</EntryPointSymbol>
<AdditionalDependencies>d3d9.lib;opengl32.lib;libucrt.lib;libvcruntime.lib;dbghelp.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -175,7 +175,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>main</EntryPointSymbol>
<AdditionalDependencies>d3d9.lib;opengl32.lib;libucrt.lib;libvcruntime.lib;dbghelp.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>d3d9.lib;opengl32.lib;ws2_32.lib;Wininet.lib;dbghelp.lib;Winmm.lib;libucrt.lib;libvcruntime.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -242,6 +242,7 @@
<ClInclude Include="Typedefs.h" />
<ClInclude Include="Vectors.h" />
<ClInclude Include="VertexStructs.h" />
<ClInclude Include="Vorbis.h" />
<ClInclude Include="Widgets.h" />
<ClInclude Include="Window.h" />
<ClInclude Include="World.h" />
@ -306,6 +307,7 @@
<ClCompile Include="TexturePack.c" />
<ClCompile Include="Utils.c" />
<ClCompile Include="Vectors.c" />
<ClCompile Include="Vorbis.c" />
<ClCompile Include="Widgets.c" />
<ClCompile Include="WinErrorHandler.c" />
<ClCompile Include="WinPlatform.c" />

View File

@ -136,6 +136,12 @@
<Filter Include="Header Files\Game">
<UniqueIdentifier>{570b92b8-b3df-40cb-a42a-da14c81c877a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Audio">
<UniqueIdentifier>{fee32b2d-e320-4681-9d5d-9904ca911271}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Audio">
<UniqueIdentifier>{b6f24d6b-c6f6-4909-9ae1-f0c478846c6e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Typedefs.h">
@ -321,9 +327,6 @@
<ClInclude Include="TexturePack.h">
<Filter>Header Files\TexturePack</Filter>
</ClInclude>
<ClInclude Include="Audio.h">
<Filter>Header Files\Game</Filter>
</ClInclude>
<ClInclude Include="PacketHandlers.h">
<Filter>Header Files\Network</Filter>
</ClInclude>
@ -336,6 +339,12 @@
<ClInclude Include="EnvRenderer.h">
<Filter>Header Files\Rendering</Filter>
</ClInclude>
<ClInclude Include="Audio.h">
<Filter>Header Files\Audio</Filter>
</ClInclude>
<ClInclude Include="Vorbis.h">
<Filter>Header Files\Audio</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="WinPlatform.c">
@ -531,7 +540,10 @@
<Filter>Source Files\Platform</Filter>
</ClCompile>
<ClCompile Include="Audio.c">
<Filter>Source Files\Game</Filter>
<Filter>Source Files\Audio</Filter>
</ClCompile>
<ClCompile Include="Vorbis.c">
<Filter>Source Files\Audio</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -112,4 +112,15 @@ ReturnCode Platform_HttpGetRequestHeaders(struct AsyncRequest* request, void* ha
ReturnCode Platform_HttpGetRequestData(struct AsyncRequest* request, void* handle, void** data, UInt32 size, volatile Int32* progress);
ReturnCode Platform_HttpFreeRequest(void* handle);
ReturnCode Platform_HttpFree(void);
#define AUDIO_MAX_CHUNKS 5
struct AudioFormat { UInt8 Channels, BitsPerSample; UInt16 Frequency };
#define AudioFormat_Eq(a, b) (a->Channels == b->Channels && a->BitsPerSample == b->BitsPerSample && a->Frequency == b->Frequency)
void Platform_AudioInit(Int32* handle, UInt8 buffers);
void Platform_AudioFree(Int32 handle);
void Platform_AudioSetFormat(Int32 handle, struct AudioFormat* format);
void Platform_AudioPlayAsync(Int32 handle, void* data, UInt32 dataSize);
Int32 Platform_AudioNextFinishedAsync(Int32 handle);
bool Platform_AudioFinishedAsync(Int32 handle);
#endif

1337
src/Client/Vorbis.c Normal file

File diff suppressed because it is too large Load Diff

49
src/Client/Vorbis.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef CC_VORBIS_H
#define CC_VORBIS_H
#include "Typedefs.h"
/* Decodes ogg vorbis audio
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
struct IGameComponent;
struct Stream;
enum OGG_VER { OGG_ERR_INVALID_SIG = 2552401, OGG_ERR_VERSION };
#define OGG_BUFFER_SIZE (255 * 256)
void Ogg_MakeStream(struct Stream* stream, UInt8* buffer, struct Stream* source);
enum VORBIS_ERR {
VORBIS_ERR_HEADER = 5238001, VORBIS_ERR_WRONG_HEADER, VORBIS_ERR_FRAMING,
VORBIS_ERR_VERSION, VORBIS_ERR_BLOCKSIZE, VORBIS_ERR_CHANS,
VORBIS_ERR_TIME_TYPE, VORBIS_ERR_FLOOR_TYPE, VORBIS_ERR_RESIDUE_TYPE,
VORBIS_ERR_MAPPING_TYPE, VORBIS_ERR_MODE_TYPE,
VORBIS_ERR_CODEBOOK_SYNC, VORBIS_ERR_CODEBOOK_ENTRY, VORBIS_ERR_CODEBOOK_LOOKUP,
VORBIS_ERR_MODE_WINDOW, VORBIS_ERR_MODE_TRANSFORM,
VORBIS_ERR_MAPPING_CHANS, VORBIS_ERR_MAPPING_RESERVED,
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*/
UInt32 NumBits; /* Number of bits in Bits buffer*/
struct Stream* Source; /* Source for filling Input buffer */
UInt8 Channels, ModeNumBits;
UInt16 CurBlockSize, PrevBlockSize, DataSize;
Int32 SampleRate; Int32 BlockSizes[2];
Real32* Values;
Real32* PrevOutput[VORBIS_MAX_CHANS];
Real32* CurOutput[VORBIS_MAX_CHANS];
struct Codebook* Codebooks;
struct Floor* Floors;
struct Residue* Residues;
struct Mapping* Mappings;
struct Mode* Modes;
};
void Vorbis_Init(struct VorbisState* ctx, struct Stream* source);
ReturnCode Vorbis_DecodeHeaders(struct VorbisState* ctx);
ReturnCode Vorbis_DecodeFrame(struct VorbisState* ctx);
Int32 Vorbis_OutputFrame(struct VorbisState* ctx, Int16* data);
#endif

View File

@ -16,6 +16,7 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wininet.h>
#include <mmsystem.h>
/* Missing from some old MingW32 headers */
#define HTTP_QUERY_ETAG 54
@ -597,4 +598,97 @@ ReturnCode Platform_HttpFreeRequest(void* handle) {
ReturnCode Platform_HttpFree(void) {
return InternetCloseHandle(hInternet) ? 0 : GetLastError();
}
struct AudioContext {
HWAVEOUT Handle;
WAVEHDR Headers[AUDIO_MAX_CHUNKS];
struct AudioFormat Format;
UInt8 NumBuffers, PlayingAsync;
};
struct AudioContext Audio_Contexts[20];
void Platform_AudioInit(Int32* handle, UInt8 buffers) {
Int32 i;
for (i = 0; i < Array_Elems(Audio_Contexts); i++) {
struct AudioContext* ctx = &Audio_Contexts[i];
if (ctx->NumBuffers) continue;
ctx->NumBuffers = buffers;
*handle = i; return;
}
ErrorHandler_Fail("No free audio contexts");
}
void Platform_AudioFree(Int32 handle) {
struct AudioContext* ctx = &Audio_Contexts[handle];
if (!ctx->Handle) return;
ReturnCode result = waveOutClose(ctx->Handle);
Platform_MemSet(ctx, 0, sizeof(struct AudioContext));
ErrorHandler_CheckOrFail(result, "Audio - closing device");
}
void Platform_AudioSetFormat(Int32 handle, struct AudioFormat* format) {
struct AudioContext* ctx = &Audio_Contexts[handle];
struct AudioFormat* cur = &ctx->Format;
/* only recreate handle if we need to */
if (AudioFormat_Eq(cur, format)) return;
if (ctx->Handle) Platform_AudioFree(handle);
WAVEFORMATEX fmt = { 0 };
fmt.nChannels = format->Channels;
fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.wBitsPerSample = format->BitsPerSample;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nSamplesPerSec = format->Frequency;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
if (waveOutGetNumDevs() == 0u) ErrorHandler_Fail("No audio devices found");
ReturnCode result = waveOutOpen(&ctx->Handle, UInt32_MaxValue, &fmt, NULL, NULL, CALLBACK_NULL);
ErrorHandler_CheckOrFail(result, "Audio - opening device");
}
void Platform_AudioPlayAsync(Int32 handle, void* data, UInt32 dataSize) {
struct AudioContext* ctx = &Audio_Contexts[handle];
WAVEHDR* hdr = &ctx->Headers[0];
Platform_MemSet(hdr, 0, sizeof(WAVEHDR));
hdr->lpData = data;
hdr->dwBufferLength = dataSize;
hdr->dwLoops = 1;
ctx->PlayingAsync = true;
ReturnCode result = waveOutPrepareHeader(ctx->Handle, hdr, sizeof(WAVEHDR));
ErrorHandler_CheckOrFail(result, "Audio - prepare header");
result = waveOutWrite(ctx->Handle, hdr, sizeof(WAVEHDR));
ErrorHandler_CheckOrFail(result, "Audio - write header");
}
Int32 Platform_AudioNextFinishedAsync(Int32 handle) {
struct AudioContext* ctx = &Audio_Contexts[handle];
Int32 i;
for (i = 0; i < ctx->NumBuffers; i++) {
WAVEHDR* hdr = &ctx->Headers[i];
if (!(hdr->dwFlags & WHDR_DONE)) continue;
if (hdr->dwFlags & WHDR_PREPARED) {
ReturnCode result = waveOutUnprepareHeader(ctx->Handle, hdr, sizeof(WAVEHDR));
ErrorHandler_CheckOrFail(result, "Audio - unprepare header");
}
return i;
}
return -1;
}
bool Platform_AudioFinishedAsync(Int32 handle) {
struct AudioContext* ctx = &Audio_Contexts[handle];
if (!ctx->PlayingAsync) return true;
Int32 index = Platform_AudioNextFinishedAsync(handle);
if (index >= 0) return false;
ctx->PlayingAsync = false;
return true;
}
#endif