Add XAudio2 support to the FAudio sound backend

This commit is contained in:
David Hrdlička
2022-02-20 00:41:28 +01:00
parent 72a7c9cdcf
commit 3101d74658
5 changed files with 270 additions and 101 deletions

View File

@@ -114,8 +114,7 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# ------ ----------- ---- # ------ ----------- ----
option(RELEASE "Release build" OFF) option(RELEASE "Release build" OFF)
option(DYNAREC "Dynamic recompiler" ON) option(DYNAREC "Dynamic recompiler" ON)
option(OPENAL "OpenAL" ON) option(OPENAL "OpenAL" OFF)
option(FAUDIO "FAudio" OFF)
option(FLUIDSYNTH "FluidSynth" ON) option(FLUIDSYNTH "FluidSynth" ON)
option(MUNT "MUNT" ON) option(MUNT "MUNT" ON)
option(DINPUT "DirectInput" OFF) option(DINPUT "DirectInput" OFF)

View File

@@ -43,7 +43,7 @@ if(VNC)
add_compile_definitions(USE_VNC) add_compile_definitions(USE_VNC)
add_library(vnc OBJECT vnc.c vnc_keymap.c) add_library(vnc OBJECT vnc.c vnc_keymap.c)
target_link_libraries(86Box vnc vncserver) target_link_libraries(86Box vnc vncserver)
if (WIN32) if(WIN32)
target_link_libraries(86Box ws2_32) target_link_libraries(86Box ws2_32)
endif() endif()
endif() endif()
@@ -86,28 +86,6 @@ if(APPLE)
target_link_libraries(86Box Freetype::Freetype) target_link_libraries(86Box Freetype::Freetype)
endif() endif()
if(FAUDIO)
find_package(FAudio REQUIRED)
target_link_libraries(86Box FAudio::FAudio)
endif()
if(OPENAL AND NOT FAUDIO)
if(VCPKG_TOOLCHAIN)
find_package(OpenAL CONFIG REQUIRED)
elseif(MINGW)
find_package(OpenAL MODULE REQUIRED)
else()
find_package(OpenAL REQUIRED)
endif()
if(TARGET OpenAL::OpenAL)
target_link_libraries(86Box OpenAL::OpenAL)
else()
include_directories(${OPENAL_INCLUDE_DIR})
target_link_libraries(86Box ${OPENAL_LIBRARY})
endif()
endif()
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS}) include_directories(${SDL2_INCLUDE_DIRS})
if(STATIC_BUILD AND TARGET SDL2::SDL2-static) if(STATIC_BUILD AND TARGET SDL2::SDL2-static)

106
src/include/FAudio_compat.h Normal file
View File

@@ -0,0 +1,106 @@
/* map xaudio2 API to faudio API */
typedef uint32_t HRESULT;
typedef uint32_t UINT32;
typedef uint32_t DWORD;
typedef uint8_t BOOL;
#define WINAPI FAUDIOCALL
#define TRUE 1
#define FALSE 0
#define S_OK 0
#define XAUDIO2_E_INVALID_CALL FAUDIO_E_INVALID_CALL
#define XAUDIO2_DEFAULT_PROCESSOR FAUDIO_DEFAULT_PROCESSOR
#define XAUDIO2_COMMIT_NOW FAUDIO_COMMIT_NOW
#define XAUDIO2_END_OF_STREAM FAUDIO_END_OF_STREAM
#define WAVE_FORMAT_PCM FAUDIO_FORMAT_PCM
#define WAVE_FORMAT_IEEE_FLOAT FAUDIO_FORMAT_IEEE_FLOAT
#define AudioCategory_GameEffects FAudioStreamCategory_GameEffects
#define GlobalDefaultDevice FAudioGlobalDefaultDevice
#define NotDefaultDevice FAudioNotDefaultDevice
#define XAudio2Create FAudioCreate
typedef FAudioBuffer XAUDIO2_BUFFER;
typedef FAudioDeviceDetails XAUDIO2_DEVICE_DETAILS;
typedef FAudioEffectChain XAUDIO2_EFFECT_CHAIN;
typedef FAudioEffectDescriptor XAUDIO2_EFFECT_DESCRIPTOR;
typedef FAudioVoiceDetails XAUDIO2_VOICE_DETAILS;
typedef FAudioVoiceDetails XAUDIO27_VOICE_DETAILS;
typedef FAudioVoiceState XAUDIO2_VOICE_STATE;
typedef FAudioWaveFormatEx WAVEFORMATEX;
typedef FAudioPerformanceData XAUDIO2_PERFORMANCE_DATA;
typedef FAudioEngineCallback IXAudio2EngineCallback;
typedef FAudioVoiceCallback IXAudio2VoiceCallback;
typedef FAPO IXAPO;
typedef FAudio IXAudio27;
#define IXAudio27_CreateMasteringVoice FAudio_CreateMasteringVoice
#define IXAudio27_CreateSourceVoice FAudio_CreateSourceVoice
#define IXAudio27_CreateSubmixVoice FAudio_CreateSubmixVoice
#define IXAudio27_GetDeviceCount FAudio_GetDeviceCount
#define IXAudio27_GetDeviceDetails FAudio_GetDeviceDetails
#define IXAudio27_GetPerformanceData FAudio_GetPerformanceData
#define IXAudio27_Initialize FAudio_Initialize
#define IXAudio27_RegisterForCallbacks FAudio_RegisterForCallbacks
#define IXAudio27_Release FAudio_Release
#define IXAudio27_StartEngine FAudio_StartEngine
#define IXAudio27_StopEngine FAudio_StopEngine
#define IXAudio27_UnregisterForCallbacks FAudio_UnregisterForCallbacks
typedef FAudio IXAudio2;
#define IXAudio2_CreateMasteringVoice FAudio_CreateMasteringVoice8
#define IXAudio2_CreateSourceVoice FAudio_CreateSourceVoice
#define IXAudio2_CreateSubmixVoice FAudio_CreateSubmixVoice
#define IXAudio2_GetPerformanceData FAudio_GetPerformanceData
#define IXAudio2_RegisterForCallbacks FAudio_RegisterForCallbacks
#define IXAudio2_Release FAudio_Release
#define IXAudio2_StartEngine FAudio_StartEngine
#define IXAudio2_StopEngine FAudio_StopEngine
#define IXAudio2_UnregisterForCallbacks FAudio_UnregisterForCallbacks
typedef FAudioMasteringVoice IXAudio2MasteringVoice;
#define IXAudio2MasteringVoice_DestroyVoice FAudioVoice_DestroyVoice
#define IXAudio2MasteringVoice_GetChannelMask FAudioMasteringVoice_GetChannelMask
#define IXAudio2MasteringVoice_SetEffectChain FAudioVoice_SetEffectChain
#define IXAudio2MasteringVoice_SetVolume FAudioVoice_SetVolume
typedef FAudioSourceVoice IXAudio27SourceVoice;
#define IXAudio27SourceVoice_DestroyVoice FAudioVoice_DestroyVoice
#define IXAudio27SourceVoice_ExitLoop FAudioSourceVoice_ExitLoop
#define IXAudio27SourceVoice_FlushSourceBuffers FAudioSourceVoice_FlushSourceBuffers
#define IXAudio27SourceVoice_GetState(a,b) FAudioSourceVoice_GetState(a,b,0)
#define IXAudio27SourceVoice_GetVoiceDetails FAudioVoice_GetVoiceDetails
#define IXAudio27SourceVoice_SetChannelVolumes FAudioVoice_SetChannelVolumes
#define IXAudio27SourceVoice_SetSourceSampleRate FAudioSourceVoice_SetSourceSampleRate
#define IXAudio27SourceVoice_Start FAudioSourceVoice_Start
#define IXAudio27SourceVoice_Stop FAudioSourceVoice_Stop
#define IXAudio27SourceVoice_SubmitSourceBuffer FAudioSourceVoice_SubmitSourceBuffer
typedef FAudioSourceVoice IXAudio2SourceVoice;
#define IXAudio2SourceVoice_DestroyVoice FAudioVoice_DestroyVoice
#define IXAudio2SourceVoice_ExitLoop FAudioSourceVoice_ExitLoop
#define IXAudio2SourceVoice_FlushSourceBuffers FAudioSourceVoice_FlushSourceBuffers
#define IXAudio2SourceVoice_GetState FAudioSourceVoice_GetState
#define IXAudio2SourceVoice_GetVoiceDetails FAudioVoice_GetVoiceDetails
#define IXAudio2SourceVoice_SetChannelVolumes FAudioVoice_SetChannelVolumes
#define IXAudio2SourceVoice_SetSourceSampleRate FAudioSourceVoice_SetSourceSampleRate
#define IXAudio2SourceVoice_SetVolume FAudioVoice_SetVolume
#define IXAudio2SourceVoice_Start FAudioSourceVoice_Start
#define IXAudio2SourceVoice_Stop FAudioSourceVoice_Stop
#define IXAudio2SourceVoice_SubmitSourceBuffer FAudioSourceVoice_SubmitSourceBuffer
typedef FAudioSubmixVoice IXAudio27SubmixVoice;
#define IXAudio27SubmixVoice_GetVoiceDetails FAudioVoice_GetVoiceDetails
#define IXAudio27SubmixVoice_DestroyVoice FAudioVoice_DestroyVoice
typedef FAudioSubmixVoice IXAudio2SubmixVoice;
#define IXAudio2SubmixVoice_GetVoiceDetails FAudioVoice_GetVoiceDetails
#define IXAudio2SubmixVoice_DestroyVoice FAudioVoice_DestroyVoice

View File

@@ -19,12 +19,38 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_resid.cc
snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c
snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c)
if(OPENAL OR FAUDIO) if(OPENAL)
target_compile_definitions(snd PRIVATE USE_OPENAL) if(VCPKG_TOOLCHAIN)
if (FAUDIO) find_package(OpenAL CONFIG REQUIRED)
target_sources(snd PRIVATE faudio.cpp) elseif(MINGW)
find_package(OpenAL MODULE REQUIRED)
else() else()
target_sources(snd PRIVATE openal.c) find_package(OpenAL REQUIRED)
endif()
if(TARGET OpenAL::OpenAL)
target_link_libraries(86Box OpenAL::OpenAL)
else()
include_directories(${OPENAL_INCLUDE_DIR})
target_link_libraries(86Box ${OPENAL_LIBRARY})
endif()
target_sources(snd PRIVATE openal.c)
else()
if(WIN32)
option(FAUDIO "Use FAudio instead of XAudio2" OFF)
endif()
target_sources(snd PRIVATE xaudio2.c)
if(NOT WIN32 OR FAUDIO)
find_package(PkgConfig REQUIRED)
# Use FAudio, a reimplementation of XAudio2
pkg_check_modules(FAUDIO REQUIRED IMPORTED_TARGET FAudio)
target_link_libraries(86Box PkgConfig::FAUDIO)
set_property(SOURCE xaudio2.c PROPERTY COMPILE_DEFINITIONS USE_FAUDIO)
endif() endif()
endif() endif()

View File

@@ -6,7 +6,7 @@
* *
* This file is part of the 86Box distribution. * This file is part of the 86Box distribution.
* *
* Interface to the FAudio audio processing library. * Interface to the XAudio2 audio processing library.
* *
* *
* *
@@ -20,95 +20,152 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
#include <FAudio.h>
extern "C" #if defined(_WIN32) && !defined(USE_FAUDIO)
{ #define COBJMACROS
#include <xaudio2.h>
#else
#include <FAudio.h>
#include <FAudio_compat.h>
#endif
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/sound.h> #include <86box/sound.h>
#include <86box/midi.h> #include <86box/midi.h>
#include <86box/plat_dynld.h>
#if defined(_WIN32) && !defined(USE_FAUDIO)
static void *xaudio2_handle = NULL;
static HRESULT (WINAPI *pXAudio2Create)(IXAudio2** ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor);
static dllimp_t xaudio2_imports[] = {
{ "XAudio2Create", &pXAudio2Create },
{ NULL, NULL },
};
#define XAudio2Create pXAudio2Create
#endif
static int midi_freq = 44100; static int midi_freq = 44100;
static int midi_buf_size = 4410; static int midi_buf_size = 4410;
static int initialized = 0; static int initialized = 0;
static FAudio* faudio = nullptr; static IXAudio2 *xaudio2 = NULL;
static FAudioMasteringVoice* mastervoice = nullptr; static IXAudio2MasteringVoice *mastervoice = NULL;
static FAudioSourceVoice* srcvoice = nullptr; static IXAudio2SourceVoice *srcvoice = NULL;
static FAudioSourceVoice* srcvoicemidi = nullptr; static IXAudio2SourceVoice *srcvoicemidi = NULL;
static FAudioSourceVoice* srcvoicecd = nullptr; static IXAudio2SourceVoice *srcvoicecd = NULL;
#define FREQ 48000 #define FREQ 48000
#define BUFLEN SOUNDBUFLEN #define BUFLEN SOUNDBUFLEN
static void FAUDIOCALL static void WINAPI OnVoiceProcessingPassStart(IXAudio2VoiceCallback *callback, uint32_t bytesRequired) {}
onBufferFinished( static void WINAPI OnVoiceProcessingPassEnd(IXAudio2VoiceCallback *callback) {}
FAudioVoiceCallback *callback, static void WINAPI OnStreamEnd(IXAudio2VoiceCallback *callback) {}
void *pBufferContext) static void WINAPI OnBufferStart(IXAudio2VoiceCallback *callback, void *pBufferContext) {}
static void WINAPI OnLoopEnd(IXAudio2VoiceCallback *callback, void *pBufferContext) {}
static void WINAPI OnVoiceError(IXAudio2VoiceCallback *callback, void *pBufferContext, HRESULT error) {}
static void WINAPI
OnBufferEnd(IXAudio2VoiceCallback *callback, void *pBufferContext)
{ {
if (sound_is_float) delete[] (float*)(pBufferContext); free(pBufferContext);
else delete[] (int16_t*)(pBufferContext);
} }
static FAudioVoiceCallback callbacks = #if defined(_WIN32) && !defined(USE_FAUDIO)
static IXAudio2VoiceCallbackVtbl callbacksVtbl =
#else
static FAudioVoiceCallback callbacks =
#endif
{ {
onBufferFinished .OnVoiceProcessingPassStart = OnVoiceProcessingPassStart,
.OnVoiceProcessingPassEnd = OnVoiceProcessingPassEnd,
.OnStreamEnd = OnStreamEnd,
.OnBufferStart = OnBufferStart,
.OnBufferEnd = OnBufferEnd,
.OnLoopEnd = OnLoopEnd,
.OnVoiceError = OnVoiceError
}; };
#if defined(_WIN32) && !defined(USE_FAUDIO)
static IXAudio2VoiceCallback callbacks = { &callbacksVtbl };
#endif
void void
inital() inital()
{ {
if (FAudioCreate(&faudio, 0, FAUDIO_DEFAULT_PROCESSOR)) #if defined(_WIN32) && !defined(USE_FAUDIO)
if (xaudio2_handle == NULL) {
xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports);
}
if (xaudio2_handle == NULL) {
xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports);
}
if (xaudio2_handle == NULL) {
return;
}
#endif
if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR))
{ {
return; return;
} }
if (FAudio_CreateMasteringVoice(faudio, &mastervoice, 2, FREQ, 0, 0, nullptr)) if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0))
{ {
FAudio_Release(faudio); IXAudio2_Release(xaudio2);
faudio = nullptr; xaudio2 = NULL;
return; return;
} }
FAudioWaveFormatEx fmt;
WAVEFORMATEX fmt;
fmt.nChannels = 2; fmt.nChannels = 2;
if (sound_is_float) if (sound_is_float)
{ {
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
fmt.wBitsPerSample = 32; fmt.wBitsPerSample = 32;
} }
else else
{ {
fmt.wFormatTag = FAUDIO_FORMAT_PCM; fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.wBitsPerSample = 16; fmt.wBitsPerSample = 16;
} }
fmt.nSamplesPerSec = FREQ; fmt.nSamplesPerSec = FREQ;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
fmt.cbSize = 0; fmt.cbSize = 0;
if (FAudio_CreateSourceVoice(faudio, &srcvoice, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr))
if (IXAudio2_CreateSourceVoice(xaudio2, &srcvoice, &fmt, 0, 2.0f, &callbacks, NULL, NULL))
{ {
FAudioVoice_DestroyVoice(mastervoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice);
FAudio_Release(faudio); IXAudio2_Release(xaudio2);
faudio = nullptr; xaudio2 = NULL;
mastervoice = nullptr; mastervoice = NULL;
return; return;
} }
fmt.nSamplesPerSec = CD_FREQ; fmt.nSamplesPerSec = CD_FREQ;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
FAudio_CreateSourceVoice(faudio, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
FAudioVoice_SetVolume(srcvoice, 1, FAUDIO_COMMIT_NOW); IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
FAudioSourceVoice_Start(srcvoice, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_Start(srcvoicecd, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW);
auto mdn = midi_device_get_internal_name(midi_device_current); IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW);
IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
char *mdn = midi_device_get_internal_name(midi_device_current);
if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME))
{ {
fmt.nSamplesPerSec = midi_freq; fmt.nSamplesPerSec = midi_freq;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr); IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
} }
initialized = 1; initialized = 1;
} }
@@ -117,52 +174,57 @@ closeal()
{ {
if (!initialized) return; if (!initialized) return;
initialized = 0; initialized = 0;
FAudioSourceVoice_Stop(srcvoice, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoice); IXAudio2SourceVoice_FlushSourceBuffers(srcvoice);
FAudioSourceVoice_Stop(srcvoicecd, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicecd); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd);
if (srcvoicemidi) if (srcvoicemidi)
{ {
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
FAudioVoice_DestroyVoice(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi);
} }
FAudioVoice_DestroyVoice(srcvoice); IXAudio2SourceVoice_DestroyVoice(srcvoice);
FAudioVoice_DestroyVoice(srcvoicecd); IXAudio2SourceVoice_DestroyVoice(srcvoicecd);
FAudioVoice_DestroyVoice(mastervoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice);
FAudio_Release(faudio); IXAudio2_Release(xaudio2);
srcvoice = srcvoicecd = srcvoicemidi = nullptr; srcvoice = srcvoicecd = srcvoicemidi = NULL;
mastervoice = nullptr; mastervoice = NULL;
faudio = nullptr; xaudio2 = NULL;
#if defined(_WIN32) && !defined(USE_FAUDIO)
dynld_close(xaudio2_handle);
xaudio2_handle = NULL;
#endif
} }
void void
givealbuffer_common(void *buf, FAudioSourceVoice* sourcevoice, size_t buflen) givealbuffer_common(void *buf, IXAudio2SourceVoice* sourcevoice, size_t buflen)
{ {
if (!initialized) return; if (!initialized) return;
FAudioVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), FAUDIO_COMMIT_NOW); IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), XAUDIO2_COMMIT_NOW);
FAudioBuffer buffer{}; XAUDIO2_BUFFER buffer = {0};
buffer.Flags = 0; buffer.Flags = 0;
if (sound_is_float) if (sound_is_float)
{ {
buffer.pAudioData = (uint8_t*)new float[buflen]; buffer.pAudioData = calloc(buflen, sizeof(float));
buffer.AudioBytes = (buflen) * sizeof(float); buffer.AudioBytes = (buflen) * sizeof(float);
} }
else else
{ {
buffer.pAudioData = (uint8_t*)new int16_t[buflen]; buffer.pAudioData = calloc(buflen, sizeof(int16_t));
buffer.AudioBytes = (buflen) * sizeof(int16_t); buffer.AudioBytes = (buflen) * sizeof(int16_t);
} }
if (buffer.pAudioData == nullptr) if (buffer.pAudioData == NULL)
{ {
fatal("faudio: Out Of Memory!"); fatal("xaudio2: Out Of Memory!");
} }
memcpy((void*)buffer.pAudioData, buf, buffer.AudioBytes); memcpy((void*)buffer.pAudioData, buf, buffer.AudioBytes);
buffer.PlayBegin = buffer.PlayLength = 0; buffer.PlayBegin = buffer.PlayLength = 0;
buffer.PlayLength = buflen >> 1; buffer.PlayLength = buflen >> 1;
buffer.pContext = (void*)buffer.pAudioData; buffer.pContext = (void*)buffer.pAudioData;
FAudioSourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, nullptr); IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL);
} }
void void
@@ -185,28 +247,28 @@ al_set_midi(int freq, int buf_size)
if (initialized && srcvoicemidi) if (initialized && srcvoicemidi)
{ {
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi); IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
FAudioVoice_DestroyVoice(srcvoicemidi); IXAudio2SourceVoice_DestroyVoice(srcvoicemidi);
srcvoicemidi = nullptr; srcvoicemidi = NULL;
FAudioWaveFormatEx fmt; WAVEFORMATEX fmt;
fmt.nChannels = 2; fmt.nChannels = 2;
if (sound_is_float) if (sound_is_float)
{ {
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
fmt.wBitsPerSample = 32; fmt.wBitsPerSample = 32;
} }
else else
{ {
fmt.wFormatTag = FAUDIO_FORMAT_PCM; fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.wBitsPerSample = 16; fmt.wBitsPerSample = 16;
} }
fmt.nSamplesPerSec = midi_freq; fmt.nSamplesPerSec = midi_freq;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
fmt.cbSize = 0; fmt.cbSize = 0;
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr); IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW); IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
} }
} }
@@ -215,5 +277,3 @@ givealbuffer_midi(void *buf, uint32_t size)
{ {
givealbuffer_common(buf, srcvoicemidi, size); givealbuffer_common(buf, srcvoicemidi, size);
} }
}