mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 03:08:41 +00:00
fix sound playing, we are actually playing an audio file :)
This commit is contained in:
parent
f7b67e4116
commit
44ebefd06a
|
|
@ -55,7 +55,7 @@ void ams_create(AssetManagementSystem* ams, BufferMemory* buf, int chunk_size, i
|
|||
ams->asset_data_memory.chunk_size = chunk_size;
|
||||
ams->asset_data_memory.last_pos = -1;
|
||||
ams->asset_data_memory.alignment = 1;
|
||||
ams->asset_data_memory.memory = buffer_get_memory(buf, chunk_size * count);
|
||||
ams->asset_data_memory.memory = buffer_get_memory(buf, chunk_size * count, 64);
|
||||
ams->asset_data_memory.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(uint64));
|
||||
|
||||
ams->first = NULL;
|
||||
|
|
|
|||
34
audio/Audio.cpp
Normal file
34
audio/Audio.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_AUDIO_C
|
||||
#define TOS_AUDIO_C
|
||||
|
||||
#include "../utils/StringUtils.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/UtilsWin32.h"
|
||||
#else
|
||||
#include "../platform/linux/UtilsLinux.h"
|
||||
#endif
|
||||
|
||||
#include "Audio.h"
|
||||
#include "Wav.h"
|
||||
|
||||
void audio_from_file(RingMemory* ring, const char* path, Audio* audio)
|
||||
{
|
||||
FileBody file;
|
||||
file_read(path, &file, ring);
|
||||
|
||||
if (str_ends_with(path, ".wav")) {
|
||||
wav_audio_generate(&file, audio);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -10,14 +10,37 @@
|
|||
#define TOS_AUDIO_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/UtilsWin32.h"
|
||||
#else
|
||||
#include "../platform/linux/UtilsLinux.h"
|
||||
#endif
|
||||
|
||||
#include "Audio.h"
|
||||
|
||||
struct Audio {
|
||||
uint32 sample_rate; // bits_per_sample
|
||||
uint32 sample_size; // byte_per_bloc
|
||||
uint32 frequency;
|
||||
// bits per sample
|
||||
// usually 48000 or 44100
|
||||
uint32 sample_rate;
|
||||
|
||||
// bytes per bloc
|
||||
// channel count * bit
|
||||
// usually 2 * 16 = 4
|
||||
uint32 sample_size;
|
||||
|
||||
// audio channels
|
||||
// usually 2
|
||||
uint32 channels;
|
||||
|
||||
// usually 16 = 2
|
||||
uint32 bloc_size;
|
||||
|
||||
// sample_rate * sample_size
|
||||
uint32 byte_per_sec;
|
||||
|
||||
uint32 size;
|
||||
byte* data; // owner of data
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,13 +15,28 @@
|
|||
#define SOUND_API_XAUDIO2 1
|
||||
|
||||
struct AudioSetting {
|
||||
// bits per sample
|
||||
// usually 48000 or 44100
|
||||
uint32 sample_rate;
|
||||
|
||||
// bytes per bloc
|
||||
// channel count * bit
|
||||
// usually 2 * 16 = 4
|
||||
uint32 sample_size;
|
||||
|
||||
// position in the audio data
|
||||
// WARNING: not the byte position, but the index based on the sample size
|
||||
uint32 sample_index;
|
||||
|
||||
uint32 latency;
|
||||
|
||||
// how often has the audio_play been called (required for xaudio)
|
||||
uint32 sample_output;
|
||||
|
||||
// 0 - 100
|
||||
int16 volume;
|
||||
|
||||
// max buffer content/size
|
||||
uint32 buffer_size;
|
||||
|
||||
// Actual samples inside the buffer
|
||||
|
|
@ -31,6 +46,8 @@ struct AudioSetting {
|
|||
|
||||
bool is_playing = false;
|
||||
byte type = SOUND_API_DIRECT_SOUND;
|
||||
|
||||
// @todo add more settings e.g. repeat etc
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
17
audio/Wav.h
17
audio/Wav.h
|
|
@ -64,7 +64,7 @@ void generate_default_wav_references(const FileBody* file, Wav* wav)
|
|||
|
||||
// Check if we can copy memory directly
|
||||
// The struct layout and header size should match on x86, but we still check it
|
||||
if (sizeof(WavHeader) == WAV_HEADER_SIZE) {
|
||||
if constexpr (sizeof(WavHeader) == WAV_HEADER_SIZE) {
|
||||
memcpy(&wav->header, file->content, WAV_HEADER_SIZE);
|
||||
|
||||
// swap endian if we are on big endian system
|
||||
|
|
@ -129,23 +129,26 @@ void generate_default_wav_references(const FileBody* file, Wav* wav)
|
|||
wav->header.data_size = SWAP_ENDIAN_LITTLE(*((uint32 *) *(wav->data + 40)));
|
||||
}
|
||||
|
||||
wav->sample_data = wav->data + WAV_HEADER_SIZE;
|
||||
wav->sample_data = wav->data + WAV_HEADER_SIZE;
|
||||
}
|
||||
|
||||
void generate_wav_audio(const FileBody* src_data, Audio* audio)
|
||||
void wav_audio_generate(const FileBody* src_data, Audio* audio)
|
||||
{
|
||||
// @performance We are generating the struct and then filling the data.
|
||||
// There is some asignment/copy overhead
|
||||
Wav src = {};
|
||||
generate_default_wav_references(src_data, &src);
|
||||
|
||||
audio->sample_rate = src.header.bits_per_sample;
|
||||
audio->sample_size = src.header.byte_per_bloc;
|
||||
audio->frequency = src.header.frequency;
|
||||
if (!src.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
audio->sample_rate = src.header.frequency;
|
||||
audio->sample_size = (src.header.bits_per_sample / 8) * src.header.nbr_channels;
|
||||
audio->channels = src.header.nbr_channels;
|
||||
audio->byte_per_sec = src.header.byte_per_sec;
|
||||
audio->bloc_size = src.header.bloc_size;
|
||||
audio->size = src.size - WAV_HEADER_SIZE;
|
||||
audio->size = src.header.data_size;
|
||||
|
||||
memcpy((void *) audio->data, src.sample_data, audio->size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ camera_update_vectors(Camera* camera)
|
|||
vec3_normalize_f32(&camera->up);
|
||||
}
|
||||
|
||||
void camera_rotate(Camera* camera, float dx, float dy, float dt)
|
||||
void camera_rotate(Camera* camera, int32 dx, int32 dy, float dt)
|
||||
{
|
||||
camera->orientation.x += dy * camera->sensitivity;
|
||||
camera->orientation.y -= dx * camera->sensitivity;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// @todo Make this file not rely on any other header except Types.
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../platform/win32/UtilsWin32.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ void debug_memory_add_range(DebugMemory* mem, uint64 start, uint64 end)
|
|||
inline
|
||||
void debug_memory_reset(DebugMemory* mem)
|
||||
{
|
||||
mem->size = 0;
|
||||
mem->usage = 0;
|
||||
|
||||
mem->debug_range_idx = 0;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ bool library_load(Library* lib)
|
|||
|
||||
lib->is_valid = true;
|
||||
for (int c = 0; c < lib->function_count; ++c) {
|
||||
void* function = GetProcAddress(lib->handle, lib->function_names[c]);
|
||||
void* function = (void *) GetProcAddress(lib->handle, (LPCSTR) lib->function_names[c]);
|
||||
if (function) {
|
||||
lib->functions[c] = function;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@
|
|||
#include "../../../stdlib/Types.h"
|
||||
#include "../../../audio/AudioSetting.h"
|
||||
#include "../../../utils/MathUtils.h"
|
||||
#include "../../../log/Log.h"
|
||||
|
||||
struct DirectSoundSetting {
|
||||
LPDIRECTSOUND8 direct_sound;
|
||||
LPDIRECTSOUND8 audio_handle;
|
||||
LPDIRECTSOUNDBUFFER primary_buffer;
|
||||
LPDIRECTSOUNDBUFFER secondary_buffer;
|
||||
};
|
||||
|
|
@ -32,19 +33,21 @@ HRESULT WINAPI DirectSoundCreate8Stub(LPCGUID, LPDIRECTSOUND8*, LPUNKNOWN) {
|
|||
void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_setting) {
|
||||
HMODULE lib = LoadLibraryExA((LPCSTR) "dsound.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!lib) {
|
||||
// @todo Log
|
||||
LOG(log_memory, "DirectSound: Couldn't load dsound.dll\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
audio_create* DirectSoundCreate8 = (audio_create *) GetProcAddress(lib, "DirectSoundCreate8");
|
||||
|
||||
if (!DirectSoundCreate8 || !SUCCEEDED(DirectSoundCreate8(0, &api_setting->direct_sound, 0))) {
|
||||
// @todo Log
|
||||
if (!DirectSoundCreate8 || !SUCCEEDED(DirectSoundCreate8(0, &api_setting->audio_handle, 0))) {
|
||||
LOG(log_memory, "DirectSound: DirectSoundCreate8 failed\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!SUCCEEDED(api_setting->direct_sound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY))) {
|
||||
// @todo Log
|
||||
if(!SUCCEEDED(api_setting->audio_handle->SetCooperativeLevel(hwnd, DSSCL_PRIORITY))) {
|
||||
LOG(log_memory, "DirectSound: SetCooperativeLevel failed.\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -59,35 +62,36 @@ void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_settin
|
|||
wf.cbSize = 0;
|
||||
|
||||
// Create primary buffer
|
||||
DSBUFFERDESC bufferDesc;
|
||||
ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC));
|
||||
DSBUFFERDESC buffer_desc;
|
||||
ZeroMemory(&buffer_desc, sizeof(DSBUFFERDESC));
|
||||
|
||||
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
buffer_desc.dwSize = sizeof(DSBUFFERDESC);
|
||||
buffer_desc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
|
||||
if(!SUCCEEDED(api_setting->direct_sound->CreateSoundBuffer(&bufferDesc, &api_setting->primary_buffer, 0))) {
|
||||
// @todo Log
|
||||
if(!SUCCEEDED(api_setting->audio_handle->CreateSoundBuffer(&buffer_desc, &api_setting->primary_buffer, 0))) {
|
||||
LOG(log_memory, "DirectSound: CreateSoundBuffer1 failed.\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(api_setting->primary_buffer->SetFormat(&wf))) {
|
||||
// @todo Log
|
||||
LOG(log_memory, "DirectSound: SetFormat failed.\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Create secondary buffer
|
||||
DSBUFFERDESC bufferDesc2;
|
||||
ZeroMemory(&bufferDesc2, sizeof(DSBUFFERDESC));
|
||||
DSBUFFERDESC buffer_desc2;
|
||||
ZeroMemory(&buffer_desc2, sizeof(DSBUFFERDESC));
|
||||
|
||||
bufferDesc2.dwSize = sizeof(DSBUFFERDESC);
|
||||
bufferDesc2.dwFlags = 0;
|
||||
bufferDesc2.dwBufferBytes = setting->buffer_size;
|
||||
bufferDesc2.lpwfxFormat = &wf;
|
||||
buffer_desc2.dwSize = sizeof(DSBUFFERDESC);
|
||||
// @todo check alterntaive flags
|
||||
buffer_desc2.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLFX | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2;
|
||||
buffer_desc2.dwBufferBytes = setting->buffer_size;
|
||||
buffer_desc2.lpwfxFormat = &wf;
|
||||
|
||||
if(!SUCCEEDED(api_setting->direct_sound->CreateSoundBuffer(&bufferDesc2, &api_setting->secondary_buffer, 0))) {
|
||||
// @todo Log
|
||||
if(!SUCCEEDED(api_setting->audio_handle->CreateSoundBuffer(&buffer_desc2, &api_setting->secondary_buffer, 0))) {
|
||||
LOG(log_memory, "DirectSound: CreateSoundBuffer2 failed.\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -107,8 +111,8 @@ void audio_play(AudioSetting* setting, DirectSoundSetting* api_setting)
|
|||
inline
|
||||
void audio_free(AudioSetting*, DirectSoundSetting* api_setting)
|
||||
{
|
||||
if (api_setting->direct_sound) {
|
||||
api_setting->direct_sound->Release();
|
||||
if (api_setting->audio_handle) {
|
||||
api_setting->audio_handle->Release();
|
||||
}
|
||||
|
||||
if (api_setting->primary_buffer) {
|
||||
|
|
@ -129,7 +133,8 @@ uint32 audio_buffer_fillable(const AudioSetting* setting, const DirectSoundSetti
|
|||
DWORD player_cursor;
|
||||
DWORD write_cursor;
|
||||
if (!SUCCEEDED(api_setting->secondary_buffer->GetCurrentPosition(&player_cursor, &write_cursor))) {
|
||||
// @todo Log
|
||||
LOG(log_memory, "DirectSound: GetCurrentPosition failed.\n", log_fp, true, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -151,12 +156,16 @@ uint32 audio_buffer_fillable(const AudioSetting* setting, const DirectSoundSetti
|
|||
}
|
||||
|
||||
inline
|
||||
void audio_play_buffer(AudioSetting* setting, DirectSoundSetting* api_setting, uint32 bytes_to_write)
|
||||
void audio_play_buffer(AudioSetting* setting, DirectSoundSetting* api_setting)
|
||||
{
|
||||
if (bytes_to_write == 0) {
|
||||
if (setting->sample_buffer_size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!setting->is_playing) {
|
||||
audio_play(setting, api_setting);
|
||||
}
|
||||
|
||||
void *region1;
|
||||
DWORD region1_size;
|
||||
|
||||
|
|
@ -166,16 +175,12 @@ void audio_play_buffer(AudioSetting* setting, DirectSoundSetting* api_setting, u
|
|||
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
|
||||
|
||||
api_setting->secondary_buffer->Lock(
|
||||
bytes_to_lock, bytes_to_write,
|
||||
bytes_to_lock, setting->sample_buffer_size,
|
||||
®ion1, ®ion1_size,
|
||||
®ion2, ®ion2_size,
|
||||
0
|
||||
);
|
||||
|
||||
// @question Do we even need to use memcpy? Can't we use the buffer directly?
|
||||
// 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,
|
||||
|
|
@ -192,7 +197,7 @@ void audio_play_buffer(AudioSetting* setting, DirectSoundSetting* api_setting, u
|
|||
|
||||
api_setting->secondary_buffer->Unlock(region1, region1_size, region2, region2_size);
|
||||
|
||||
setting->sample_index += bytes_to_write / setting->sample_size;
|
||||
setting->sample_index += setting->sample_buffer_size / setting->sample_size;
|
||||
setting->sample_buffer_size = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@
|
|||
|
||||
#include <xaudio2.h>
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../../../audio/AudioSetting.h"
|
||||
#include "../../../utils/MathUtils.h"
|
||||
#include "../../../log/Log.h"
|
||||
|
||||
struct XAudio2Setting {
|
||||
IXAudio2* xaudio2;
|
||||
IXAudio2* audio_handle;
|
||||
IXAudio2SourceVoice* source_voice;
|
||||
IXAudio2MasteringVoice* mastering_voice;
|
||||
|
||||
|
|
@ -32,31 +34,37 @@ HRESULT WINAPI XAudio2CreateStub(IXAudio2**, UINT32, XAUDIO2_PROCESSOR) {
|
|||
// END: Dynamically load XAudio2
|
||||
|
||||
void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) {
|
||||
CoInitialize(NULL);
|
||||
HMODULE lib = LoadLibraryExA((LPCSTR) "xaudio2_9.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!lib) {
|
||||
// @todo Log
|
||||
LOG(log_memory, "Xaudio2: Couldn't load xaudio2_9.dll\n", log_fp, true, true);
|
||||
|
||||
lib = LoadLibraryExA((LPCSTR) "xaudio2_8.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
|
||||
if (!lib) {
|
||||
// @todo Log
|
||||
LOG(log_memory, "Xaudio2: Couldn't load xaudio2_8.dll\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
audio_create* XAudio2Create = (audio_create *) GetProcAddress(lib, "XAudio2Create");
|
||||
if (!XAudio2Create || !SUCCEEDED(XAudio2Create(&api_setting->xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR))) {
|
||||
// @todo Log
|
||||
if (!XAudio2Create || !SUCCEEDED(XAudio2Create(&api_setting->audio_handle, 0, XAUDIO2_DEFAULT_PROCESSOR))) {
|
||||
LOG(log_memory, "Xaudio2: XAudio2Create failed\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(api_setting->xaudio2->CreateMasteringVoice(
|
||||
HRESULT hr;
|
||||
if (!SUCCEEDED(hr = api_setting->audio_handle->CreateMasteringVoice(
|
||||
&api_setting->mastering_voice,
|
||||
XAUDIO2_DEFAULT_CHANNELS,
|
||||
setting->sample_rate,
|
||||
0,
|
||||
NULL
|
||||
))) {
|
||||
// @todo Log
|
||||
NULL))
|
||||
) {
|
||||
LOG(log_memory, "Xaudio2: CreateMasteringVoice failed\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -69,15 +77,16 @@ void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) {
|
|||
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; // = buffer_size
|
||||
wf.cbSize = 0;
|
||||
|
||||
if (!SUCCEEDED(api_setting->xaudio2->CreateSourceVoice(&api_setting->source_voice, &wf))) {
|
||||
// @todo Log
|
||||
if (!SUCCEEDED(api_setting->audio_handle->CreateSourceVoice(&api_setting->source_voice, &wf))) {
|
||||
LOG(log_memory, "Xaudio2: CreateSourceVoice failed\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo consider to remove mallocs/callocs
|
||||
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?
|
||||
api_setting->internal_buffer[0].Flags = 0;
|
||||
api_setting->internal_buffer[0].AudioBytes = setting->buffer_size;
|
||||
api_setting->internal_buffer[0].pAudioData = (byte *) malloc(setting->buffer_size * sizeof(byte));
|
||||
|
|
@ -104,13 +113,15 @@ void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) {
|
|||
inline
|
||||
void audio_play(AudioSetting* setting, XAudio2Setting* api_setting) {
|
||||
if (!api_setting->source_voice) {
|
||||
// @todo Log
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
api_setting->source_voice->Start(0, XAUDIO2_COMMIT_NOW);
|
||||
setting->is_playing = true;
|
||||
|
||||
if (setting->sample_index > 1) {
|
||||
setting->sample_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -136,8 +147,8 @@ void audio_free(AudioSetting* setting, XAudio2Setting* api_setting)
|
|||
api_setting->mastering_voice->DestroyVoice();
|
||||
}
|
||||
|
||||
if (api_setting->xaudio2) {
|
||||
api_setting->xaudio2->Release();
|
||||
if (api_setting->audio_handle) {
|
||||
api_setting->audio_handle->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,8 +162,6 @@ inline
|
|||
uint32 audio_buffer_fillable(const AudioSetting* setting, const XAudio2Setting* api_setting)
|
||||
{
|
||||
if (!api_setting->source_voice) {
|
||||
// @todo Log
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -166,29 +175,30 @@ uint32 audio_buffer_fillable(const AudioSetting* setting, const XAudio2Setting*
|
|||
}
|
||||
|
||||
inline
|
||||
void audio_play_buffer(AudioSetting* setting, XAudio2Setting* api_setting, uint32 bytes_to_write) {
|
||||
if (!api_setting->source_voice) {
|
||||
// @todo Log
|
||||
|
||||
void audio_play_buffer(AudioSetting* setting, XAudio2Setting* api_setting) {
|
||||
if (!api_setting->source_voice || setting->sample_buffer_size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_to_write == 0) {
|
||||
return;
|
||||
if (!setting->is_playing) {
|
||||
audio_play(setting, api_setting);
|
||||
}
|
||||
|
||||
uint32 idx = setting->sample_output % 2;
|
||||
|
||||
memcpy(
|
||||
(void *) api_setting->internal_buffer[setting->sample_index].pAudioData,
|
||||
(void *) api_setting->internal_buffer[idx].pAudioData,
|
||||
setting->buffer,
|
||||
bytes_to_write
|
||||
setting->sample_buffer_size
|
||||
);
|
||||
|
||||
if (!SUCCEEDED(api_setting->source_voice->SubmitSourceBuffer(&api_setting->internal_buffer[setting->sample_index]))) {
|
||||
// @todo Log
|
||||
if (!SUCCEEDED(api_setting->source_voice->SubmitSourceBuffer(&api_setting->internal_buffer[idx]))) {
|
||||
LOG(log_memory, "Xaudio2: SubmitSourceBuffer failed\n", log_fp, true, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setting->sample_index = (setting->sample_index + 1) % 2;
|
||||
setting->sample_index += setting->sample_buffer_size / setting->sample_size;
|
||||
setting->sample_buffer_size = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user