Add XAudio2 support to the FAudio sound backend
This commit is contained in:
@@ -114,8 +114,7 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||
# ------ ----------- ----
|
||||
option(RELEASE "Release build" OFF)
|
||||
option(DYNAREC "Dynamic recompiler" ON)
|
||||
option(OPENAL "OpenAL" ON)
|
||||
option(FAUDIO "FAudio" OFF)
|
||||
option(OPENAL "OpenAL" OFF)
|
||||
option(FLUIDSYNTH "FluidSynth" ON)
|
||||
option(MUNT "MUNT" ON)
|
||||
option(DINPUT "DirectInput" OFF)
|
||||
|
@@ -43,7 +43,7 @@ if(VNC)
|
||||
add_compile_definitions(USE_VNC)
|
||||
add_library(vnc OBJECT vnc.c vnc_keymap.c)
|
||||
target_link_libraries(86Box vnc vncserver)
|
||||
if (WIN32)
|
||||
if(WIN32)
|
||||
target_link_libraries(86Box ws2_32)
|
||||
endif()
|
||||
endif()
|
||||
@@ -86,28 +86,6 @@ if(APPLE)
|
||||
target_link_libraries(86Box Freetype::Freetype)
|
||||
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)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
if(STATIC_BUILD AND TARGET SDL2::SDL2-static)
|
||||
|
106
src/include/FAudio_compat.h
Normal file
106
src/include/FAudio_compat.h
Normal 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
|
@@ -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_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c)
|
||||
|
||||
if(OPENAL OR FAUDIO)
|
||||
target_compile_definitions(snd PRIVATE USE_OPENAL)
|
||||
if (FAUDIO)
|
||||
target_sources(snd PRIVATE faudio.cpp)
|
||||
if(OPENAL)
|
||||
if(VCPKG_TOOLCHAIN)
|
||||
find_package(OpenAL CONFIG REQUIRED)
|
||||
elseif(MINGW)
|
||||
find_package(OpenAL MODULE REQUIRED)
|
||||
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()
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* 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 <stdlib.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/sound.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_buf_size = 4410;
|
||||
static int initialized = 0;
|
||||
static FAudio* faudio = nullptr;
|
||||
static FAudioMasteringVoice* mastervoice = nullptr;
|
||||
static FAudioSourceVoice* srcvoice = nullptr;
|
||||
static FAudioSourceVoice* srcvoicemidi = nullptr;
|
||||
static FAudioSourceVoice* srcvoicecd = nullptr;
|
||||
static IXAudio2 *xaudio2 = NULL;
|
||||
static IXAudio2MasteringVoice *mastervoice = NULL;
|
||||
static IXAudio2SourceVoice *srcvoice = NULL;
|
||||
static IXAudio2SourceVoice *srcvoicemidi = NULL;
|
||||
static IXAudio2SourceVoice *srcvoicecd = NULL;
|
||||
|
||||
#define FREQ 48000
|
||||
#define BUFLEN SOUNDBUFLEN
|
||||
|
||||
static void FAUDIOCALL
|
||||
onBufferFinished(
|
||||
FAudioVoiceCallback *callback,
|
||||
void *pBufferContext)
|
||||
static void WINAPI OnVoiceProcessingPassStart(IXAudio2VoiceCallback *callback, uint32_t bytesRequired) {}
|
||||
static void WINAPI OnVoiceProcessingPassEnd(IXAudio2VoiceCallback *callback) {}
|
||||
static void WINAPI OnStreamEnd(IXAudio2VoiceCallback *callback) {}
|
||||
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);
|
||||
else delete[] (int16_t*)(pBufferContext);
|
||||
|
||||
free(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
|
||||
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;
|
||||
}
|
||||
|
||||
if (FAudio_CreateMasteringVoice(faudio, &mastervoice, 2, FREQ, 0, 0, nullptr))
|
||||
if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0))
|
||||
{
|
||||
FAudio_Release(faudio);
|
||||
faudio = nullptr;
|
||||
IXAudio2_Release(xaudio2);
|
||||
xaudio2 = NULL;
|
||||
return;
|
||||
}
|
||||
FAudioWaveFormatEx fmt;
|
||||
|
||||
WAVEFORMATEX fmt;
|
||||
fmt.nChannels = 2;
|
||||
|
||||
if (sound_is_float)
|
||||
{
|
||||
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
|
||||
fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
fmt.wBitsPerSample = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.wFormatTag = FAUDIO_FORMAT_PCM;
|
||||
fmt.wFormatTag = WAVE_FORMAT_PCM;
|
||||
fmt.wBitsPerSample = 16;
|
||||
}
|
||||
|
||||
fmt.nSamplesPerSec = FREQ;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
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);
|
||||
FAudio_Release(faudio);
|
||||
faudio = nullptr;
|
||||
mastervoice = nullptr;
|
||||
IXAudio2MasteringVoice_DestroyVoice(mastervoice);
|
||||
IXAudio2_Release(xaudio2);
|
||||
xaudio2 = NULL;
|
||||
mastervoice = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
fmt.nSamplesPerSec = CD_FREQ;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
FAudio_CreateSourceVoice(faudio, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
|
||||
FAudioVoice_SetVolume(srcvoice, 1, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_Start(srcvoice, 0, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_Start(srcvoicecd, 0, FAUDIO_COMMIT_NOW);
|
||||
auto mdn = midi_device_get_internal_name(midi_device_current);
|
||||
|
||||
IXAudio2_CreateSourceVoice(xaudio2, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
|
||||
|
||||
IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW);
|
||||
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))
|
||||
{
|
||||
{
|
||||
fmt.nSamplesPerSec = midi_freq;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
|
||||
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
|
||||
IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
|
||||
IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
@@ -117,52 +174,57 @@ closeal()
|
||||
{
|
||||
if (!initialized) return;
|
||||
initialized = 0;
|
||||
FAudioSourceVoice_Stop(srcvoice, 0, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_FlushSourceBuffers(srcvoice);
|
||||
FAudioSourceVoice_Stop(srcvoicecd, 0, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_FlushSourceBuffers(srcvoicecd);
|
||||
IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoice);
|
||||
IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd);
|
||||
if (srcvoicemidi)
|
||||
{
|
||||
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi);
|
||||
FAudioVoice_DestroyVoice(srcvoicemidi);
|
||||
IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicemidi);
|
||||
}
|
||||
FAudioVoice_DestroyVoice(srcvoice);
|
||||
FAudioVoice_DestroyVoice(srcvoicecd);
|
||||
FAudioVoice_DestroyVoice(mastervoice);
|
||||
FAudio_Release(faudio);
|
||||
srcvoice = srcvoicecd = srcvoicemidi = nullptr;
|
||||
mastervoice = nullptr;
|
||||
faudio = nullptr;
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoice);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicecd);
|
||||
IXAudio2MasteringVoice_DestroyVoice(mastervoice);
|
||||
IXAudio2_Release(xaudio2);
|
||||
srcvoice = srcvoicecd = srcvoicemidi = NULL;
|
||||
mastervoice = NULL;
|
||||
xaudio2 = NULL;
|
||||
|
||||
#if defined(_WIN32) && !defined(USE_FAUDIO)
|
||||
dynld_close(xaudio2_handle);
|
||||
xaudio2_handle = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_common(void *buf, FAudioSourceVoice* sourcevoice, size_t buflen)
|
||||
givealbuffer_common(void *buf, IXAudio2SourceVoice* sourcevoice, size_t buflen)
|
||||
{
|
||||
if (!initialized) return;
|
||||
|
||||
FAudioVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), FAUDIO_COMMIT_NOW);
|
||||
FAudioBuffer buffer{};
|
||||
IXAudio2MasteringVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), XAUDIO2_COMMIT_NOW);
|
||||
XAUDIO2_BUFFER buffer = {0};
|
||||
buffer.Flags = 0;
|
||||
if (sound_is_float)
|
||||
{
|
||||
buffer.pAudioData = (uint8_t*)new float[buflen];
|
||||
buffer.pAudioData = calloc(buflen, sizeof(float));
|
||||
buffer.AudioBytes = (buflen) * sizeof(float);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.pAudioData = (uint8_t*)new int16_t[buflen];
|
||||
buffer.pAudioData = calloc(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);
|
||||
buffer.PlayBegin = buffer.PlayLength = 0;
|
||||
buffer.PlayLength = buflen >> 1;
|
||||
buffer.pContext = (void*)buffer.pAudioData;
|
||||
FAudioSourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, nullptr);
|
||||
IXAudio2SourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,28 +247,28 @@ al_set_midi(int freq, int buf_size)
|
||||
|
||||
if (initialized && srcvoicemidi)
|
||||
{
|
||||
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
|
||||
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi);
|
||||
FAudioVoice_DestroyVoice(srcvoicemidi);
|
||||
srcvoicemidi = nullptr;
|
||||
FAudioWaveFormatEx fmt;
|
||||
IXAudio2SourceVoice_Stop(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicemidi);
|
||||
srcvoicemidi = NULL;
|
||||
WAVEFORMATEX fmt;
|
||||
fmt.nChannels = 2;
|
||||
if (sound_is_float)
|
||||
{
|
||||
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
|
||||
fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
fmt.wBitsPerSample = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.wFormatTag = FAUDIO_FORMAT_PCM;
|
||||
fmt.wFormatTag = WAVE_FORMAT_PCM;
|
||||
fmt.wBitsPerSample = 16;
|
||||
}
|
||||
fmt.nSamplesPerSec = midi_freq;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
fmt.cbSize = 0;
|
||||
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
|
||||
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
|
||||
IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
|
||||
IXAudio2SourceVoice_Start(srcvoicemidi, 0, XAUDIO2_COMMIT_NOW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,5 +277,3 @@ givealbuffer_midi(void *buf, uint32_t size)
|
||||
{
|
||||
givealbuffer_common(buf, srcvoicemidi, size);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user