mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-02-14 09:28:41 +00:00
update
Some checks failed
Some checks failed
This commit is contained in:
parent
02ee4480ad
commit
e939a3f4a6
101
Compression/LZP.h
Normal file
101
Compression/LZP.h
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* Jingga
|
||||||
|
*
|
||||||
|
* @package Models
|
||||||
|
* @copyright Dennis Eichhorn
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @version 1.0.0
|
||||||
|
* @link https://jingga.app
|
||||||
|
*/
|
||||||
|
#ifndef COMPRESSION_LZP_H
|
||||||
|
#define COMPRESSION_LZP_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../Stdlib/Types.h"
|
||||||
|
|
||||||
|
uint32 encode_lzp(const byte* in, uint32 length, byte* out)
|
||||||
|
{
|
||||||
|
byte buf[9];
|
||||||
|
byte table[1 << 16] = {0};
|
||||||
|
|
||||||
|
uint16 hash = 0;
|
||||||
|
int32 mask, i, j, c, in_pos = 0, out_pos = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
j = 1;
|
||||||
|
mask = 0;
|
||||||
|
for (i = 0; i < 8; ++i) {
|
||||||
|
if (in_pos == length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = in[in_pos++];
|
||||||
|
if (c == table[hash]) {
|
||||||
|
mask |= 1 << i;
|
||||||
|
} else {
|
||||||
|
table[hash] = c;
|
||||||
|
buf[j++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = (hash << 4) ^ c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
buf[0] = mask;
|
||||||
|
for (i = 0; i < j; ++i) {
|
||||||
|
out[out_pos++] = buf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_pos == length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 decode_lzp(const byte* in, uint32 length, byte* out)
|
||||||
|
{
|
||||||
|
byte buf[8];
|
||||||
|
byte table[1 << 16] = {0};
|
||||||
|
|
||||||
|
uint16 hash = 0;
|
||||||
|
int mask, i, j, c, in_pos = 0, out_pos = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
j = 0;
|
||||||
|
if (in_pos == length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = in[in_pos++];
|
||||||
|
for (i = 0; i < 8; ++i) {
|
||||||
|
if ((mask & (1 << i)) != 0) {
|
||||||
|
c = table[hash];
|
||||||
|
} else {
|
||||||
|
if (in_pos == length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = in[in_pos++];
|
||||||
|
table[hash] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[j++] = c;
|
||||||
|
|
||||||
|
hash = (hash << 4) ^ c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
for (i = 0; i < j; ++i) {
|
||||||
|
out[out_pos++] = buf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -25,8 +25,14 @@ namespace Sound {
|
||||||
uint32 sample_rate;
|
uint32 sample_rate;
|
||||||
uint32 sample_size;
|
uint32 sample_size;
|
||||||
uint32 sample_index;
|
uint32 sample_index;
|
||||||
|
|
||||||
int16 volume;
|
int16 volume;
|
||||||
|
|
||||||
uint32 buffer_size;
|
uint32 buffer_size;
|
||||||
|
|
||||||
|
// Actual samples inside the buffer
|
||||||
|
// The buffer could be larger than the data to output
|
||||||
|
uint32 sample_buffer_size;
|
||||||
int16* buffer;
|
int16* buffer;
|
||||||
|
|
||||||
bool playing = false;
|
bool playing = false;
|
||||||
|
|
@ -61,6 +67,8 @@ namespace Sound {
|
||||||
|
|
||||||
if(!SUCCEEDED(setting->direct_sound->SetCooperativeLevel(w->hwnd, DSSCL_PRIORITY))) {
|
if(!SUCCEEDED(setting->direct_sound->SetCooperativeLevel(w->hwnd, DSSCL_PRIORITY))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WAVEFORMATEX wf = {};
|
WAVEFORMATEX wf = {};
|
||||||
|
|
@ -81,13 +89,18 @@ namespace Sound {
|
||||||
|
|
||||||
if(!SUCCEEDED(setting->direct_sound->CreateSoundBuffer(&bufferDesc, &setting->primary_buffer, 0))) {
|
if(!SUCCEEDED(setting->direct_sound->CreateSoundBuffer(&bufferDesc, &setting->primary_buffer, 0))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(setting->primary_buffer->SetFormat(&wf))) {
|
if (!SUCCEEDED(setting->primary_buffer->SetFormat(&wf))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->buffer_size = setting->sample_rate * setting->sample_size;
|
setting->buffer_size = setting->sample_rate * setting->sample_size;
|
||||||
|
setting->buffer = (int16 *) calloc(setting->sample_rate, setting->sample_size);
|
||||||
|
|
||||||
// Create secondary buffer
|
// Create secondary buffer
|
||||||
DSBUFFERDESC bufferDesc2;
|
DSBUFFERDESC bufferDesc2;
|
||||||
|
|
@ -100,15 +113,19 @@ namespace Sound {
|
||||||
|
|
||||||
if(!SUCCEEDED(setting->direct_sound->CreateSoundBuffer(&bufferDesc2, &setting->secondary_buffer, 0))) {
|
if(!SUCCEEDED(setting->direct_sound->CreateSoundBuffer(&bufferDesc2, &setting->secondary_buffer, 0))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
void direct_sound_play(DirectSoundSetting* setting)
|
void direct_sound_play(DirectSoundSetting* setting)
|
||||||
{
|
{
|
||||||
setting->secondary_buffer->Play(0, 0, DSBPLAY_LOOPING);
|
setting->secondary_buffer->Play(0, 0, DSBPLAY_LOOPING);
|
||||||
setting->playing = true;
|
setting->playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
void direct_sound_free(DirectSoundSetting* setting)
|
void direct_sound_free(DirectSoundSetting* setting)
|
||||||
{
|
{
|
||||||
if (setting->direct_sound) {
|
if (setting->direct_sound) {
|
||||||
|
|
@ -124,31 +141,19 @@ namespace Sound {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool direct_sound_should_update(DirectSoundSetting* setting)
|
/**
|
||||||
{
|
* Calculates the samples in bytes to generate for the buffer
|
||||||
return true;
|
*/
|
||||||
}
|
inline
|
||||||
|
uint32 direct_sound_sample_buffer_size(const DirectSoundSetting* setting)
|
||||||
int16 *direct_sound_return_buffer(DirectSoundSetting* setting)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void direct_sound_play_buffer(DirectSoundSetting* setting)
|
|
||||||
{
|
{
|
||||||
DWORD player_cursor;
|
DWORD player_cursor;
|
||||||
DWORD write_cursor;
|
DWORD write_cursor;
|
||||||
if (!SUCCEEDED(setting->secondary_buffer->GetCurrentPosition(&player_cursor, &write_cursor))) {
|
if (!SUCCEEDED(setting->secondary_buffer->GetCurrentPosition(&player_cursor, &write_cursor))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *region1;
|
|
||||||
DWORD region1_size;
|
|
||||||
|
|
||||||
void *region2;
|
|
||||||
DWORD region2_size;
|
|
||||||
|
|
||||||
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
|
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
|
||||||
DWORD bytes_to_write = 0;
|
DWORD bytes_to_write = 0;
|
||||||
|
|
||||||
|
|
@ -161,6 +166,24 @@ namespace Sound {
|
||||||
bytes_to_write = player_cursor - bytes_to_lock;
|
bytes_to_write = player_cursor - bytes_to_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bytes_to_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void direct_sound_play_buffer(DirectSoundSetting* setting, uint32 bytes_to_write)
|
||||||
|
{
|
||||||
|
if (bytes_to_write == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *region1;
|
||||||
|
DWORD region1_size;
|
||||||
|
|
||||||
|
void *region2;
|
||||||
|
DWORD region2_size;
|
||||||
|
|
||||||
|
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
|
||||||
|
|
||||||
setting->secondary_buffer->Lock(
|
setting->secondary_buffer->Lock(
|
||||||
bytes_to_lock, bytes_to_write,
|
bytes_to_lock, bytes_to_write,
|
||||||
®ion1, ®ion1_size,
|
®ion1, ®ion1_size,
|
||||||
|
|
@ -168,31 +191,28 @@ namespace Sound {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
int16* sample_out = (int16 *) region1;
|
// @question Do we even need to use memcpy? Can't we use the buffer directly?
|
||||||
DWORD region1_sample_count = region1_size / setting->sample_size;
|
// Probably depends on what lock actually does to region1/region2
|
||||||
|
// Of course we would than need some mechanism to check when we can write into the buffer
|
||||||
|
// See XAudio2 for this, we would probably need a second buffer as well
|
||||||
|
memcpy(
|
||||||
|
(void *) region1,
|
||||||
|
(void *) setting->buffer,
|
||||||
|
region1_size
|
||||||
|
);
|
||||||
|
|
||||||
for (DWORD idx = 0; idx < region1_sample_count; ++idx) {
|
if (region2_size > 0) {
|
||||||
f32 t = ((f32) 1.0f / (f32) (48000 / 256)) * 2.0f * OMS_PI;
|
memcpy(
|
||||||
f32 sine_value = sinf(t);
|
(void *) region2,
|
||||||
int16 sample_value = (int16) (sine_value * setting->volume);
|
(void *) (setting->buffer + region1_size),
|
||||||
|
region2_size
|
||||||
*sample_out++ = sample_value;
|
);
|
||||||
*sample_out++ = sample_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample_out = (int16 *) region2;
|
|
||||||
DWORD region2_sample_count = region2_size / setting->sample_size;
|
|
||||||
|
|
||||||
for (DWORD idx = 0; idx < region2_sample_count; ++idx) {
|
|
||||||
f32 t = ((f32) 1.0f / (f32) (48000 / 256)) * 2.0f * OMS_PI;
|
|
||||||
f32 sine_value = sinf(t);
|
|
||||||
int16 sample_value = (int16) (sine_value * setting->volume);
|
|
||||||
|
|
||||||
*sample_out++ = sample_value;
|
|
||||||
*sample_out++ = sample_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->secondary_buffer->Unlock(region1, region1_size, region2, region2_size);
|
setting->secondary_buffer->Unlock(region1, region1_size, region2, region2_size);
|
||||||
|
|
||||||
|
setting->sample_index += bytes_to_write / setting->sample_size;
|
||||||
|
setting->sample_buffer_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
119
Sound/XAudio2.h
119
Sound/XAudio2.h
|
|
@ -25,9 +25,16 @@ namespace Sound {
|
||||||
uint32 sample_rate;
|
uint32 sample_rate;
|
||||||
uint32 sample_size;
|
uint32 sample_size;
|
||||||
uint32 sample_index;
|
uint32 sample_index;
|
||||||
|
|
||||||
int16 volume;
|
int16 volume;
|
||||||
|
|
||||||
uint32 buffer_size;
|
uint32 buffer_size;
|
||||||
|
|
||||||
|
// Actual samples inside the buffer
|
||||||
|
// The buffer could be larger than the data to output
|
||||||
|
uint32 sample_buffer_size;
|
||||||
|
int16* buffer;
|
||||||
|
|
||||||
bool playing = false;
|
bool playing = false;
|
||||||
byte type = SOUND_API_XAUDIO2;
|
byte type = SOUND_API_XAUDIO2;
|
||||||
|
|
||||||
|
|
@ -36,7 +43,7 @@ namespace Sound {
|
||||||
IXAudio2SourceVoice* source_voice;
|
IXAudio2SourceVoice* source_voice;
|
||||||
IXAudio2MasteringVoice* mastering_voice;
|
IXAudio2MasteringVoice* mastering_voice;
|
||||||
|
|
||||||
XAUDIO2_BUFFER buffer[2];
|
XAUDIO2_BUFFER internal_buffer[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
// BEGIN: Dynamically load XAudio2
|
// BEGIN: Dynamically load XAudio2
|
||||||
|
|
@ -64,7 +71,13 @@ namespace Sound {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(setting->xaudio2->CreateMasteringVoice(&setting->mastering_voice))) {
|
if (!SUCCEEDED(setting->xaudio2->CreateMasteringVoice(
|
||||||
|
&setting->mastering_voice,
|
||||||
|
XAUDIO2_DEFAULT_CHANNELS,
|
||||||
|
setting->sample_rate,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -72,10 +85,10 @@ namespace Sound {
|
||||||
WAVEFORMATEX wf = {};
|
WAVEFORMATEX wf = {};
|
||||||
wf.wFormatTag = WAVE_FORMAT_PCM;
|
wf.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
wf.nChannels = 2;
|
wf.nChannels = 2;
|
||||||
wf.wBitsPerSample = 16;
|
wf.wBitsPerSample = (uint16) ((setting->sample_size * 8) / wf.nChannels); // = sample_size per channel
|
||||||
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8;
|
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8; // = sample_szie
|
||||||
wf.nSamplesPerSec = setting->sample_rate;
|
wf.nSamplesPerSec = setting->sample_rate;
|
||||||
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
|
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; // = buffer_size
|
||||||
wf.cbSize = 0;
|
wf.cbSize = 0;
|
||||||
|
|
||||||
if (!SUCCEEDED(setting->xaudio2->CreateSourceVoice(&setting->source_voice, &wf))) {
|
if (!SUCCEEDED(setting->xaudio2->CreateSourceVoice(&setting->source_voice, &wf))) {
|
||||||
|
|
@ -83,32 +96,34 @@ namespace Sound {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->buffer_size = setting->sample_rate * wf.nBlockAlign;
|
setting->buffer_size = setting->sample_rate * setting->sample_size;
|
||||||
|
setting->buffer = (int16 *) calloc(setting->sample_rate, setting->sample_size);
|
||||||
|
|
||||||
// @question Consider to move to the heap?
|
// @question Consider to move to the heap?
|
||||||
setting->buffer[0].Flags = 0;
|
setting->internal_buffer[0].Flags = 0;
|
||||||
setting->buffer[0].AudioBytes = setting->buffer_size;
|
setting->internal_buffer[0].AudioBytes = setting->buffer_size;
|
||||||
setting->buffer[0].pAudioData = (BYTE *) malloc(setting->buffer_size * sizeof(BYTE));
|
setting->internal_buffer[0].pAudioData = (byte *) malloc(setting->buffer_size * sizeof(byte));
|
||||||
setting->buffer[0].PlayBegin = 0;
|
setting->internal_buffer[0].PlayBegin = 0;
|
||||||
setting->buffer[0].PlayLength = 0;
|
setting->internal_buffer[0].PlayLength = 0;
|
||||||
setting->buffer[0].LoopBegin = 0;
|
setting->internal_buffer[0].LoopBegin = 0;
|
||||||
setting->buffer[0].LoopLength = 0;
|
setting->internal_buffer[0].LoopLength = 0;
|
||||||
setting->buffer[0].LoopCount = 0;
|
setting->internal_buffer[0].LoopCount = 0;
|
||||||
setting->buffer[0].pContext = NULL;
|
setting->internal_buffer[0].pContext = NULL;
|
||||||
|
|
||||||
setting->buffer[1].Flags = 0;
|
setting->internal_buffer[1].Flags = 0;
|
||||||
setting->buffer[1].AudioBytes = setting->buffer_size;
|
setting->internal_buffer[1].AudioBytes = setting->buffer_size;
|
||||||
setting->buffer[1].pAudioData = (BYTE *) malloc(setting->buffer_size * sizeof(BYTE));
|
setting->internal_buffer[1].pAudioData = (byte *) malloc(setting->buffer_size * sizeof(byte));
|
||||||
setting->buffer[1].PlayBegin = 0;
|
setting->internal_buffer[1].PlayBegin = 0;
|
||||||
setting->buffer[1].PlayLength = 0;
|
setting->internal_buffer[1].PlayLength = 0;
|
||||||
setting->buffer[1].LoopBegin = 0;
|
setting->internal_buffer[1].LoopBegin = 0;
|
||||||
setting->buffer[1].LoopLength = 0;
|
setting->internal_buffer[1].LoopLength = 0;
|
||||||
setting->buffer[1].LoopCount = 0;
|
setting->internal_buffer[1].LoopCount = 0;
|
||||||
setting->buffer[1].pContext = NULL;
|
setting->internal_buffer[1].pContext = NULL;
|
||||||
|
|
||||||
setting->sample_index = 0;
|
setting->sample_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
void xaudio2_play(XAudio2Setting* setting) {
|
void xaudio2_play(XAudio2Setting* setting) {
|
||||||
if (!setting->source_voice) {
|
if (!setting->source_voice) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
@ -120,14 +135,19 @@ namespace Sound {
|
||||||
setting->playing = true;
|
setting->playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
void xaudio2_free(XAudio2Setting* setting)
|
void xaudio2_free(XAudio2Setting* setting)
|
||||||
{
|
{
|
||||||
if (setting->buffer[0].pAudioData) {
|
if (setting->internal_buffer[0].pAudioData) {
|
||||||
free((void *) setting->buffer[0].pAudioData);
|
free((void *) setting->internal_buffer[0].pAudioData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting->buffer[1].pAudioData) {
|
if (setting->internal_buffer[1].pAudioData) {
|
||||||
free((void *) setting->buffer[1].pAudioData);
|
free((void *) setting->internal_buffer[1].pAudioData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting->buffer) {
|
||||||
|
free((void *) setting->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting->source_voice) {
|
if (setting->source_voice) {
|
||||||
|
|
@ -143,46 +163,55 @@ namespace Sound {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xaudio2_should_update(XAudio2Setting* setting)
|
/**
|
||||||
|
* Calculates the samples to generate for the buffer
|
||||||
|
*
|
||||||
|
* For XAudio2 we currently always fill the entire buffer size.
|
||||||
|
* For other audio APIs we maybe have to do something else
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
uint32 xaudio2_sample_buffer_size(XAudio2Setting* setting)
|
||||||
{
|
{
|
||||||
if (!setting->source_voice) {
|
if (!setting->source_voice) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XAUDIO2_VOICE_STATE state;
|
XAUDIO2_VOICE_STATE state;
|
||||||
setting->source_voice->GetState(&state);
|
setting->source_voice->GetState(&state);
|
||||||
if (state.BuffersQueued > 1) {
|
if (state.BuffersQueued > 1) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return setting->buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16* xaudio2_return_buffer(XAudio2Setting* setting)
|
inline
|
||||||
{
|
void xaudio2_play_buffer(XAudio2Setting* setting, uint32 bytes_to_write) {
|
||||||
return (int16 *) setting->buffer[setting->sample_index].pAudioData;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16* xaudio2_fill_buffer(XAudio2Setting* setting, int16* buffer)
|
|
||||||
{
|
|
||||||
int16* sample_out = (int16 *) setting->buffer[setting->sample_index].pAudioData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xaudio2_play_buffer(XAudio2Setting* setting) {
|
|
||||||
if (!setting->source_voice) {
|
if (!setting->source_voice) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->sample_index = (setting->sample_index + 1) % 2;
|
if (bytes_to_write == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(setting->source_voice->SubmitSourceBuffer(&setting->buffer[setting->sample_index]))) {
|
memcpy(
|
||||||
|
(void *) setting->internal_buffer[setting->sample_index].pAudioData,
|
||||||
|
setting->buffer,
|
||||||
|
bytes_to_write
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(setting->source_voice->SubmitSourceBuffer(&setting->internal_buffer[setting->sample_index]))) {
|
||||||
// @todo Log
|
// @todo Log
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setting->sample_index = (setting->sample_index + 1) % 2;
|
||||||
|
setting->sample_buffer_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ typedef uint16_t uint16;
|
||||||
typedef uint32_t uint32;
|
typedef uint32_t uint32;
|
||||||
typedef uint64_t uint64;
|
typedef uint64_t uint64;
|
||||||
|
|
||||||
|
typedef uint16_t f16;
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
||||||
|
|
@ -32,4 +33,71 @@ typedef unsigned char byte;
|
||||||
#define local_persist static
|
#define local_persist static
|
||||||
#define global_persist static
|
#define global_persist static
|
||||||
|
|
||||||
|
#define HALF_FLOAT_SIGN_MASK 0x8000
|
||||||
|
#define HALF_FLOAT_EXP_MASK 0x7C00
|
||||||
|
#define HALF_FLOAT_FRAC_MASK 0x03FF
|
||||||
|
|
||||||
|
#define HALF_FLOAT_EXP_SHIFT 10
|
||||||
|
#define HALF_FLOAT_EXP_BIAS 15
|
||||||
|
|
||||||
|
#define FLOAT32_SIGN_MASK 0x80000000
|
||||||
|
#define FLOAT32_EXP_MASK 0x7F800000
|
||||||
|
#define FLOAT32_FRAC_MASK 0x007FFFFF
|
||||||
|
|
||||||
|
#define FLOAT32_EXP_SHIFT 23
|
||||||
|
#define FLOAT32_EXP_BIAS 127
|
||||||
|
|
||||||
|
uint16 float_to_f16(float f) {
|
||||||
|
uint32_t f_bits = *((uint32_t*)&f);
|
||||||
|
uint16_t f16_bits = 0;
|
||||||
|
|
||||||
|
// Extract sign, exponent, and fraction from float
|
||||||
|
uint16_t sign = (f_bits & FLOAT32_SIGN_MASK) >> 16;
|
||||||
|
int32_t exponent = ((f_bits & FLOAT32_EXP_MASK) >> FLOAT32_EXP_SHIFT) - FLOAT32_EXP_BIAS + HALF_FLOAT_EXP_BIAS;
|
||||||
|
uint32_t fraction = (f_bits & FLOAT32_FRAC_MASK) >> (FLOAT32_EXP_SHIFT - HALF_FLOAT_EXP_SHIFT);
|
||||||
|
|
||||||
|
if (exponent <= 0) {
|
||||||
|
if (exponent < -10) {
|
||||||
|
fraction = 0;
|
||||||
|
} else {
|
||||||
|
fraction = (fraction | 0x0400) >> (1 - exponent);
|
||||||
|
}
|
||||||
|
exponent = 0;
|
||||||
|
} else if (exponent >= 0x1F) {
|
||||||
|
exponent = 0x1F;
|
||||||
|
fraction = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f16_bits = sign | (exponent << HALF_FLOAT_EXP_SHIFT) | (fraction & HALF_FLOAT_FRAC_MASK);
|
||||||
|
|
||||||
|
return f16_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
float f16_to_float(f16 f) {
|
||||||
|
uint32_t f_bits = 0;
|
||||||
|
|
||||||
|
uint32_t sign = (f & HALF_FLOAT_SIGN_MASK) << 16;
|
||||||
|
int32_t exponent = (f & HALF_FLOAT_EXP_MASK) >> HALF_FLOAT_EXP_SHIFT;
|
||||||
|
uint32_t fraction = (f & HALF_FLOAT_FRAC_MASK) << (FLOAT32_EXP_SHIFT - HALF_FLOAT_EXP_SHIFT);
|
||||||
|
|
||||||
|
if (exponent == 0) {
|
||||||
|
if (fraction != 0) {
|
||||||
|
exponent = 1;
|
||||||
|
while ((fraction & (1 << FLOAT32_EXP_SHIFT)) == 0) {
|
||||||
|
fraction <<= 1;
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
fraction &= ~FLOAT32_EXP_MASK;
|
||||||
|
}
|
||||||
|
} else if (exponent == 0x1F) {
|
||||||
|
exponent = 0xFF;
|
||||||
|
} else {
|
||||||
|
exponent += FLOAT32_EXP_BIAS - HALF_FLOAT_EXP_BIAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_bits = sign | (exponent << FLOAT32_EXP_SHIFT) | fraction;
|
||||||
|
|
||||||
|
return *((float*)&f_bits);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ namespace Test {
|
||||||
double dt = 0.0;
|
double dt = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LogMessages {
|
||||||
|
char *messages;
|
||||||
|
};
|
||||||
|
|
||||||
void update_timing_stat(TimingStat *stat)
|
void update_timing_stat(TimingStat *stat)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -46,6 +50,12 @@ namespace Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define UPDATE_TIMING_STAT(stat) Test::update_timing_stat(stat);
|
||||||
|
#else
|
||||||
|
#define UPDATE_TIMING_STAT(stat)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ASSERT_EQUALS(a, b, t1, t2) \
|
#define ASSERT_EQUALS(a, b, t1, t2) \
|
||||||
({ \
|
({ \
|
||||||
if ((a) == (b)) { \
|
if ((a) == (b)) { \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user