git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

commit 9ae2c9fd54be78f8f16c5963a07a294cea4e6210
parent 8f8b7f6b330306ff23372679decc18c6acdfe2df
Author: Lior Halphon <LIJI32@gmail.com>
Date:   Thu, 23 Jun 2022 01:13:59 +0300

Replace SDL2 audio with XAudio2 on Windows

Diffstat:
MMakefile3++-
ASDL/audio/xaudio2.c110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -17,9 +17,11 @@ ifeq ($(PLATFORM),windows32) _ := $(shell chcp 65001) EXESUFFIX:=.exe NATIVE_CC = clang -IWindows -Wno-deprecated-declarations --target=i386-pc-windows +SDL_AUDIO_DRIVER ?= xaudio2 else EXESUFFIX:= NATIVE_CC := cc +SDL_AUDIO_DRIVER ?= sdl endif PB12_COMPRESS := build/pb12$(EXESUFFIX) @@ -47,7 +49,6 @@ endif include version.mk export VERSION CONF ?= debug -SDL_AUDIO_DRIVER ?= sdl BIN := build/bin OBJ := build/obj diff --git a/SDL/audio/xaudio2.c b/SDL/audio/xaudio2.c @@ -0,0 +1,110 @@ +#include "audio.h" +#include <Windows.h> +#include <xaudio2.h> + +#define AUDIO_FREQUENCY 96000 +static IXAudio2 *xaudio2 = NULL; +static IXAudio2MasteringVoice *master_voice = NULL; +static IXAudio2SourceVoice *source_voice = NULL; +static bool playing = false; +static GB_sample_t sample_pool[0x2000]; +static unsigned pos = 0; + +#define BATCH_SIZE 256 + +static const WAVEFORMATEX wave_format = { + .wFormatTag = WAVE_FORMAT_PCM, + .nChannels = 2, + .nSamplesPerSec = AUDIO_FREQUENCY, + .nAvgBytesPerSec = AUDIO_FREQUENCY * 4, + .nBlockAlign = 4, + .wBitsPerSample = 16, + .cbSize = 0 +}; + +bool GB_audio_is_playing(void) +{ + return playing; +} + +void GB_audio_set_paused(bool paused) +{ + if (paused) { + playing = false; + IXAudio2SourceVoice_Stop(source_voice, 0, XAUDIO2_COMMIT_NOW); + GB_audio_clear_queue(); + } + else { + playing = true; + IXAudio2SourceVoice_Start(source_voice, 0, XAUDIO2_COMMIT_NOW); + } + +} + +void GB_audio_clear_queue(void) +{ + pos = 0; + IXAudio2SourceVoice_FlushSourceBuffers(source_voice); +} + +unsigned GB_audio_get_frequency(void) +{ + return AUDIO_FREQUENCY; +} + +size_t GB_audio_get_queue_length(void) +{ + static XAUDIO2_VOICE_STATE state; + IXAudio2SourceVoice_GetState(source_voice, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED); + + return state.BuffersQueued * BATCH_SIZE + (pos & (BATCH_SIZE - 1)); +} + +void GB_audio_queue_sample(GB_sample_t *sample) +{ + if (!playing) return; + + static XAUDIO2_BUFFER buffer = {.AudioBytes = sizeof(*sample) * BATCH_SIZE, }; + sample_pool[pos] = *sample; + buffer.pAudioData = (void *)&sample_pool[pos & ~(BATCH_SIZE - 1)]; + pos++; + pos &= 0x1fff; + if ((pos & (BATCH_SIZE - 1)) == 0) { + IXAudio2SourceVoice_SubmitSourceBuffer(source_voice, &buffer, NULL); + } +} + +void GB_audio_init(void) +{ + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) { + fprintf(stderr, "CoInitializeEx failed: %lx\n", hr); + return; + } + + hr = XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); + if (FAILED(hr)) { + fprintf(stderr, "XAudio2Create failed: %lx\n", hr); + return; + } + + hr = IXAudio2_CreateMasteringVoice(xaudio2, &master_voice, + 2, // 2 channels + AUDIO_FREQUENCY, + 0, // Flags + 0, // Device index + NULL, // Effect chain + AudioCategory_GameMedia // Category + ); + if (FAILED(hr)) { + fprintf(stderr, "CreateMasteringVoice failed: %lx\n", hr); + return; + } + + hr = IXAudio2_CreateSourceVoice(xaudio2, &source_voice, &wave_format, 0, XAUDIO2_DEFAULT_FREQ_RATIO, NULL, NULL, NULL); + + if (FAILED(hr)) { + fprintf(stderr, "CreateSourceVoice failed: %lx\n", hr); + return; + } +}

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.