Merge pull request #5691 from ligfx/openalonlywindowsdynamic

OpenAL: only enable on Windows + dynamically load DLL
This commit is contained in:
shuffle2 2017-06-27 01:18:06 -07:00 committed by GitHub
commit 599a235a19
14 changed files with 160 additions and 590 deletions

View File

@ -21,7 +21,6 @@ option(ENABLE_GENERIC "Enables generic build that should run on any little-endia
option(ENABLE_HEADLESS "Enables running Dolphin as a headless variant" OFF)
option(ENABLE_ALSA "Enables ALSA sound backend" ON)
option(ENABLE_PULSEAUDIO "Enables PulseAudio sound backend" ON)
option(ENABLE_OPENAL "Enables OpenAL sound backend" ON)
option(ENABLE_LLVM "Enables LLVM support, for disassembly" ON)
# Maintainers: if you consider blanket disabling this for your users, please
@ -626,8 +625,6 @@ else()
set(PNG png)
endif()
find_package(OpenAL)
# Using static soundtouch from Externals
# Unable to use system soundtouch library: We require shorts, not floats.
add_subdirectory(Externals/soundtouch)

Binary file not shown.

Binary file not shown.

View File

@ -36,7 +36,6 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClCompile Include="aldlist.cpp" />
<ClCompile Include="AudioCommon.cpp" />
<ClCompile Include="AudioStretcher.cpp" />
<ClCompile Include="CubebStream.cpp" />
@ -52,7 +51,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="aldlist.h" />
<ClInclude Include="AlsaSoundStream.h" />
<ClInclude Include="AudioCommon.h" />
<ClInclude Include="AudioStretcher.h" />

View File

@ -6,7 +6,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="aldlist.cpp" />
<ClCompile Include="AudioCommon.cpp" />
<ClCompile Include="AudioStretcher.cpp" />
<ClCompile Include="CubebUtils.cpp" />
@ -30,7 +29,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="aldlist.h" />
<ClInclude Include="AudioCommon.h" />
<ClInclude Include="AudioStretcher.h" />
<ClInclude Include="CubebUtils.h" />

View File

@ -32,23 +32,6 @@ else()
message(STATUS "ALSA explicitly disabled, disabling ALSA sound backend")
endif()
if(ENABLE_OPENAL)
if(WIN32)
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/Externals/OpenAL)
endif()
find_package(OpenAL)
if(OPENAL_FOUND)
message(STATUS "OpenAL found, enabling OpenAL sound backend")
target_sources(audiocommon PRIVATE OpenALStream.cpp aldlist.cpp)
target_link_libraries(audiocommon PRIVATE OpenAL::OpenAL)
target_compile_definitions(audiocommon PRIVATE HAVE_OPENAL=1)
else()
message(STATUS "OpenAL NOT found, disabling OpenAL sound backend")
endif()
else()
message(STATUS "OpenAL explicitly disabled, disabling OpenAL sound backend")
endif()
if(ENABLE_PULSEAUDIO)
# PulseAudio ships with a PulseAudioConfig.cmake with no imported target
# So we use our own FindPulseAudio instead with "MODULE"
@ -75,6 +58,16 @@ if(WIN32)
)
target_link_libraries(audiocommon PRIVATE audiocommon_xaudio27)
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/Externals/OpenAL)
find_package(OpenAL)
if(OPENAL_FOUND)
message(STATUS "OpenAL found, enabling OpenAL sound backend")
target_sources(audiocommon PRIVATE OpenALStream.cpp)
target_link_libraries(audiocommon PRIVATE OpenAL::OpenAL)
else()
message(FATAL_ERROR "OpenAL NOT found in Externals")
endif()
elseif(APPLE)
target_sources(audiocommon PRIVATE CoreAudioSoundStream.cpp)
endif()

View File

@ -2,70 +2,126 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#ifdef _WIN32
#include <windows.h>
#include <climits>
#include <cstring>
#include <thread>
#include "AudioCommon/OpenALStream.h"
#include "AudioCommon/aldlist.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/Thread.h"
#include "Core/ConfigManager.h"
#if defined HAVE_OPENAL && HAVE_OPENAL
static HMODULE s_openal_dll = nullptr;
#ifdef _WIN32
#pragma comment(lib, "openal32.lib")
#endif
#define OPENAL_API_VISIT(X) \
X(alBufferData) \
X(alcCloseDevice) \
X(alcCreateContext) \
X(alcDestroyContext) \
X(alcGetContextsDevice) \
X(alcGetCurrentContext) \
X(alcGetString) \
X(alcIsExtensionPresent) \
X(alcMakeContextCurrent) \
X(alcOpenDevice) \
X(alDeleteBuffers) \
X(alDeleteSources) \
X(alGenBuffers) \
X(alGenSources) \
X(alGetError) \
X(alGetSourcei) \
X(alGetString) \
X(alIsExtensionPresent) \
X(alSourcef) \
X(alSourcei) \
X(alSourcePlay) \
X(alSourceQueueBuffers) \
X(alSourceStop) \
X(alSourceUnqueueBuffers)
// Create func_t function pointer type and declare a nullptr-initialized static variable of that
// type named "pfunc".
#define DYN_FUNC_DECLARE(func) \
typedef decltype(&func) func##_t; \
static func##_t p##func = nullptr;
// Attempt to load the function from the given module handle.
#define OPENAL_FUNC_LOAD(func) \
p##func = (func##_t)::GetProcAddress(s_openal_dll, #func); \
if (!p##func) \
{ \
return false; \
}
OPENAL_API_VISIT(DYN_FUNC_DECLARE);
static bool InitFunctions()
{
OPENAL_API_VISIT(OPENAL_FUNC_LOAD);
return true;
}
static bool InitLibrary()
{
if (s_openal_dll)
return true;
s_openal_dll = ::LoadLibrary(TEXT("openal32.dll"));
if (!s_openal_dll)
return false;
if (!InitFunctions())
{
::FreeLibrary(s_openal_dll);
s_openal_dll = nullptr;
return false;
}
return true;
}
bool OpenALStream::isValid()
{
return InitLibrary();
}
//
// AyuanX: Spec says OpenAL1.1 is thread safe already
//
bool OpenALStream::Start()
{
m_run_thread.Set();
bool bReturn = false;
ALDeviceList pDeviceList;
if (pDeviceList.GetNumDevices())
{
char* defDevName = pDeviceList.GetDeviceName(pDeviceList.GetDefaultDevice());
INFO_LOG(AUDIO, "Found OpenAL device %s", defDevName);
ALCdevice* pDevice = alcOpenDevice(defDevName);
if (pDevice)
{
ALCcontext* pContext = alcCreateContext(pDevice, nullptr);
if (pContext)
{
// Used to determine an appropriate period size (2x period = total buffer size)
// ALCint refresh;
// alcGetIntegerv(pDevice, ALC_REFRESH, 1, &refresh);
// period_size_in_millisec = 1000 / refresh;
alcMakeContextCurrent(pContext);
thread = std::thread(&OpenALStream::SoundLoop, this);
bReturn = true;
}
else
{
alcCloseDevice(pDevice);
PanicAlertT("OpenAL: can't create context for device %s", defDevName);
}
}
else
{
PanicAlertT("OpenAL: can't open device %s", defDevName);
}
}
else
if (!palcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
{
PanicAlertT("OpenAL: can't find sound devices");
return false;
}
return bReturn;
const char* defaultDeviceName = palcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
INFO_LOG(AUDIO, "Found OpenAL device %s", defaultDeviceName);
ALCdevice* pDevice = palcOpenDevice(defaultDeviceName);
if (!pDevice)
{
PanicAlertT("OpenAL: can't open device %s", defaultDeviceName);
return false;
}
ALCcontext* pContext = palcCreateContext(pDevice, nullptr);
if (!pContext)
{
palcCloseDevice(pDevice);
PanicAlertT("OpenAL: can't create context for device %s", defaultDeviceName);
return false;
}
palcMakeContextCurrent(pContext);
m_run_thread.Set();
thread = std::thread(&OpenALStream::SoundLoop, this);
return true;
}
void OpenALStream::Stop()
@ -76,20 +132,20 @@ void OpenALStream::Stop()
thread.join();
alSourceStop(uiSource);
alSourcei(uiSource, AL_BUFFER, 0);
palSourceStop(uiSource);
palSourcei(uiSource, AL_BUFFER, 0);
// Clean up buffers and sources
alDeleteSources(1, &uiSource);
palDeleteSources(1, &uiSource);
uiSource = 0;
alDeleteBuffers(numBuffers, uiBuffers);
palDeleteBuffers(numBuffers, uiBuffers);
ALCcontext* pContext = alcGetCurrentContext();
ALCdevice* pDevice = alcGetContextsDevice(pContext);
ALCcontext* pContext = palcGetCurrentContext();
ALCdevice* pDevice = palcGetContextsDevice(pContext);
alcMakeContextCurrent(nullptr);
alcDestroyContext(pContext);
alcCloseDevice(pDevice);
palcMakeContextCurrent(nullptr);
palcDestroyContext(pContext);
palcCloseDevice(pDevice);
}
void OpenALStream::SetVolume(int volume)
@ -97,7 +153,7 @@ void OpenALStream::SetVolume(int volume)
fVolume = (float)volume / 100.0f;
if (uiSource)
alSourcef(uiSource, AL_GAIN, fVolume);
palSourcef(uiSource, AL_GAIN, fVolume);
}
void OpenALStream::Update()
@ -111,17 +167,17 @@ void OpenALStream::Clear(bool mute)
if (m_muted)
{
alSourceStop(uiSource);
palSourceStop(uiSource);
}
else
{
alSourcePlay(uiSource);
palSourcePlay(uiSource);
}
}
static ALenum CheckALError(const char* desc)
{
ALenum err = alGetError();
ALenum err = palGetError();
if (err != AL_NO_ERROR)
{
@ -157,15 +213,15 @@ static ALenum CheckALError(const char* desc)
static bool IsCreativeXFi()
{
return strstr(alGetString(AL_RENDERER), "X-Fi") != nullptr;
return strstr(palGetString(AL_RENDERER), "X-Fi") != nullptr;
}
void OpenALStream::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - openal");
bool float32_capable = alIsExtensionPresent("AL_EXT_float32") != 0;
bool surround_capable = alIsExtensionPresent("AL_EXT_MCFORMATS") || IsCreativeXFi();
bool float32_capable = palIsExtensionPresent("AL_EXT_float32") != 0;
bool surround_capable = palIsExtensionPresent("AL_EXT_MCFORMATS") || IsCreativeXFi();
bool use_surround = SConfig::GetInstance().bDPL2Decoder && surround_capable;
// As there is no extension to check for 32-bit fixed point support
@ -180,18 +236,18 @@ void OpenALStream::SoundLoop()
uiSource = 0;
// Clear error state before querying or else we get false positives.
ALenum err = alGetError();
ALenum err = palGetError();
// Generate some AL Buffers for streaming
alGenBuffers(numBuffers, (ALuint*)uiBuffers);
palGenBuffers(numBuffers, (ALuint*)uiBuffers);
err = CheckALError("generating buffers");
// Generate a Source to playback the Buffers
alGenSources(1, &uiSource);
palGenSources(1, &uiSource);
err = CheckALError("generating sources");
// Set the default sound volume as saved in the config file.
alSourcef(uiSource, AL_GAIN, fVolume);
palSourcef(uiSource, AL_GAIN, fVolume);
// TODO: Error handling
// ALenum err = alGetError();
@ -204,7 +260,7 @@ void OpenALStream::SoundLoop()
{
// Block until we have a free buffer
int numBuffersProcessed;
alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &numBuffersProcessed);
palGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &numBuffersProcessed);
if (numBuffers == numBuffersQueued && !numBuffersProcessed)
{
soundSyncEvent.Wait();
@ -215,7 +271,7 @@ void OpenALStream::SoundLoop()
if (numBuffersProcessed)
{
ALuint unqueuedBufferIds[OAL_MAX_BUFFERS];
alSourceUnqueueBuffers(uiSource, numBuffersProcessed, unqueuedBufferIds);
palSourceUnqueueBuffers(uiSource, numBuffersProcessed, unqueuedBufferIds);
err = CheckALError("unqueuing buffers");
numBuffersQueued -= numBuffersProcessed;
@ -245,8 +301,8 @@ void OpenALStream::SoundLoop()
if (float32_capable)
{
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, dpl2,
numSamples * FRAME_SURROUND_FLOAT, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, dpl2,
numSamples * FRAME_SURROUND_FLOAT, ulFrequency);
}
else if (fixed32_capable)
{
@ -266,8 +322,8 @@ void OpenALStream::SoundLoop()
surround_int32[i] = (int)dpl2[i];
}
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, surround_int32,
numSamples * FRAME_SURROUND_INT32, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, surround_int32,
numSamples * FRAME_SURROUND_INT32, ulFrequency);
}
else
{
@ -284,8 +340,8 @@ void OpenALStream::SoundLoop()
surround_short[i] = (int)dpl2[i];
}
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN16, surround_short,
numSamples * FRAME_SURROUND_SHORT, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN16, surround_short,
numSamples * FRAME_SURROUND_SHORT, ulFrequency);
}
err = CheckALError("buffering data");
@ -310,8 +366,8 @@ void OpenALStream::SoundLoop()
if (float32_capable)
{
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO_FLOAT32, sampleBuffer,
numSamples * FRAME_STEREO_FLOAT, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO_FLOAT32, sampleBuffer,
numSamples * FRAME_STEREO_FLOAT, ulFrequency);
err = CheckALError("buffering float32 data");
if (err == AL_INVALID_ENUM)
@ -326,8 +382,8 @@ void OpenALStream::SoundLoop()
for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
stereo_int32[i] = (int)((float)sampleBuffer[i] * (INT64_C(1) << 31));
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO32, stereo_int32,
numSamples * FRAME_STEREO_INT32, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO32, stereo_int32,
numSamples * FRAME_STEREO_INT32, ulFrequency);
}
else
{
@ -336,25 +392,25 @@ void OpenALStream::SoundLoop()
for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
stereo[i] = (short)((float)sampleBuffer[i] * (1 << 15));
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO16, stereo,
numSamples * FRAME_STEREO_SHORT, ulFrequency);
palBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO16, stereo,
numSamples * FRAME_STEREO_SHORT, ulFrequency);
}
}
alSourceQueueBuffers(uiSource, 1, &uiBuffers[nextBuffer]);
palSourceQueueBuffers(uiSource, 1, &uiBuffers[nextBuffer]);
err = CheckALError("queuing buffers");
numBuffersQueued++;
nextBuffer = (nextBuffer + 1) % numBuffers;
alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
palGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
if (iState != AL_PLAYING)
{
// Buffer underrun occurred, resume playback
alSourcePlay(uiSource);
palSourcePlay(uiSource);
err = CheckALError("occurred resuming playback");
}
}
}
#endif // HAVE_OPENAL
#endif // _WIN32

View File

@ -12,19 +12,10 @@
#include "Core/HW/AudioInterface.h"
#include "Core/HW/SystemTimers.h"
#if defined HAVE_OPENAL && HAVE_OPENAL
#ifdef _WIN32
#include <OpenAL/include/al.h>
#include <OpenAL/include/alc.h>
#include <OpenAL/include/alext.h>
#elif defined __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
#endif
#define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32
@ -40,7 +31,7 @@
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS* SIZE_FLOAT
#define FRAME_SURROUND_SHORT SURROUND_CHANNELS* SIZE_SHORT
#define FRAME_SURROUND_INT32 SURROUND_CHANNELS* SIZE_INT32
#endif
#endif // _WIN32
// From AL_EXT_float32
#ifndef AL_FORMAT_STEREO_FLOAT32
@ -63,7 +54,7 @@
class OpenALStream final : public SoundStream
{
#if defined HAVE_OPENAL && HAVE_OPENAL
#ifdef _WIN32
public:
OpenALStream() : uiSource(0) {}
bool Start() override;
@ -73,7 +64,8 @@ public:
void Clear(bool mute) override;
void Update() override;
static bool isValid() { return true; }
static bool isValid();
private:
std::thread thread;
Common::Flag m_run_thread;
@ -87,5 +79,5 @@ private:
ALfloat fVolume;
u8 numBuffers;
#endif // HAVE_OPENAL
#endif // _WIN32
};

View File

@ -1,386 +0,0 @@
// Copyright 2009 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
/*
* Copyright (c) 2006, Creative Labs Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of
* conditions and
* the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to
* endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstring>
#include "AudioCommon/aldlist.h"
#include "Common/CommonFuncs.h"
#include "Common/CommonTypes.h"
#ifdef _WIN32
#include "../../../Externals/OpenAL/include/al.h"
#include "../../../Externals/OpenAL/include/alc.h"
#elif defined(__APPLE__)
#include <al.h>
#include <alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
/*
* Init call
*/
ALDeviceList::ALDeviceList()
{
ALDEVICEINFO ALDeviceInfo;
// DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec
// version #, and extension support
vDeviceInfo.clear();
vDeviceInfo.reserve(10);
defaultDeviceIndex = 0;
// grab function pointers for 1.0-API functions, and if successful proceed to enumerate all
// devices
// if (LoadOAL10Library(nullptr, &ALFunction) == TRUE) {
if (alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
{
const char* devices = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
const char* defaultDeviceName = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
// go through device list (each device terminated with a single nullptr, list terminated with
// double nullptr)
for (s32 index = 0; devices != nullptr && strlen(devices) > 0;
index++, devices += strlen(devices) + 1)
{
if (strcmp(defaultDeviceName, devices) == 0)
{
defaultDeviceIndex = index;
}
ALCdevice* device = alcOpenDevice(devices);
if (device)
{
ALCcontext* context = alcCreateContext(device, nullptr);
if (context)
{
alcMakeContextCurrent(context);
// if new actual device name isn't already in the list, then add it...
const char* actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
bool bNewName = true;
for (s32 i = 0; i < GetNumDevices(); i++)
{
if (strcmp(GetDeviceName(i), actualDeviceName) == 0)
{
bNewName = false;
}
}
if ((bNewName) && (actualDeviceName != nullptr) && (strlen(actualDeviceName) > 0))
{
ALDeviceInfo.bSelected = true;
ALDeviceInfo.strDeviceName = actualDeviceName;
alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(s32), &ALDeviceInfo.iMajorVersion);
alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(s32), &ALDeviceInfo.iMinorVersion);
ALDeviceInfo.pvstrExtensions = new std::vector<std::string>;
// Check for ALC Extensions
if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
// Check for AL Extensions
if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
// Get Source Count
ALDeviceInfo.uiSourceCount = GetMaxNumSources();
vDeviceInfo.push_back(ALDeviceInfo);
}
alcMakeContextCurrent(nullptr);
alcDestroyContext(context);
}
alcCloseDevice(device);
}
}
}
//}
ResetFilters();
}
/*
* Exit call
*/
ALDeviceList::~ALDeviceList()
{
for (auto& di : vDeviceInfo)
{
if (di.pvstrExtensions)
{
di.pvstrExtensions->clear();
delete di.pvstrExtensions;
}
}
vDeviceInfo.clear();
}
/*
* Returns the number of devices in the complete device list
*/
s32 ALDeviceList::GetNumDevices()
{
return (s32)vDeviceInfo.size();
}
/*
* Returns the device name at an index in the complete device list
*/
char* ALDeviceList::GetDeviceName(s32 index)
{
if (index < GetNumDevices())
return (char*)vDeviceInfo[index].strDeviceName.c_str();
else
return nullptr;
}
/*
* Returns the major and minor version numbers for a device at a specified index in the complete
* list
*/
void ALDeviceList::GetDeviceVersion(s32 index, s32* major, s32* minor)
{
if (index < GetNumDevices())
{
if (major)
*major = vDeviceInfo[index].iMajorVersion;
if (minor)
*minor = vDeviceInfo[index].iMinorVersion;
}
}
/*
* Returns the maximum number of Sources that can be generate on the given device
*/
u32 ALDeviceList::GetMaxNumSources(s32 index)
{
if (index < GetNumDevices())
return vDeviceInfo[index].uiSourceCount;
else
return 0;
}
/*
* Checks if the extension is supported on the given device
*/
bool ALDeviceList::IsExtensionSupported(s32 index, char* szExtName)
{
bool bReturn = false;
if (index < GetNumDevices())
{
for (auto& ext : *vDeviceInfo[index].pvstrExtensions)
{
if (!strcasecmp(ext.c_str(), szExtName))
{
bReturn = true;
break;
}
}
}
return bReturn;
}
/*
* returns the index of the default device in the complete device list
*/
s32 ALDeviceList::GetDefaultDevice()
{
return defaultDeviceIndex;
}
/*
* Deselects devices which don't have the specified minimum version
*/
void ALDeviceList::FilterDevicesMinVer(s32 major, s32 minor)
{
s32 dMajor = 0, dMinor = 0;
for (u32 i = 0; i < vDeviceInfo.size(); i++)
{
GetDeviceVersion(i, &dMajor, &dMinor);
if ((dMajor < major) || ((dMajor == major) && (dMinor < minor)))
{
vDeviceInfo[i].bSelected = false;
}
}
}
/*
* Deselects devices which don't have the specified maximum version
*/
void ALDeviceList::FilterDevicesMaxVer(s32 major, s32 minor)
{
s32 dMajor = 0, dMinor = 0;
for (u32 i = 0; i < vDeviceInfo.size(); i++)
{
GetDeviceVersion(i, &dMajor, &dMinor);
if ((dMajor > major) || ((dMajor == major) && (dMinor > minor)))
{
vDeviceInfo[i].bSelected = false;
}
}
}
/*
* Deselects device which don't support the given extension name
*/
void ALDeviceList::FilterDevicesExtension(char* szExtName)
{
bool bFound;
for (auto& di : vDeviceInfo)
{
bFound = false;
for (auto& ext : *di.pvstrExtensions)
{
if (!strcasecmp(ext.c_str(), szExtName))
{
bFound = true;
break;
}
}
if (!bFound)
di.bSelected = false;
}
}
/*
* Resets all filtering, such that all devices are in the list
*/
void ALDeviceList::ResetFilters()
{
for (s32 i = 0; i < GetNumDevices(); i++)
{
vDeviceInfo[i].bSelected = true;
}
filterIndex = 0;
}
/*
* Gets index of first filtered device
*/
s32 ALDeviceList::GetFirstFilteredDevice()
{
s32 i;
for (i = 0; i < GetNumDevices(); i++)
{
if (vDeviceInfo[i].bSelected == true)
{
break;
}
}
filterIndex = i + 1;
return i;
}
/*
* Gets index of next filtered device
*/
s32 ALDeviceList::GetNextFilteredDevice()
{
s32 i;
for (i = filterIndex; i < GetNumDevices(); i++)
{
if (vDeviceInfo[i].bSelected == true)
{
break;
}
}
filterIndex = i + 1;
return i;
}
/*
* Internal function to determine max number of Sources that can be generated
*/
u32 ALDeviceList::GetMaxNumSources()
{
ALuint uiSources[256];
u32 iSourceCount = 0;
// Clear AL Error Code
alGetError();
// Generate up to 256 Sources, checking for any errors
for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
{
alGenSources(1, &uiSources[iSourceCount]);
if (alGetError() != AL_NO_ERROR)
break;
}
// Release the Sources
alDeleteSources(iSourceCount, uiSources);
if (alGetError() != AL_NO_ERROR)
{
for (auto& uiSource : uiSources)
{
alDeleteSources(1, &uiSource);
}
}
return iSourceCount;
}

View File

@ -1,52 +0,0 @@
// Copyright 2009 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <string>
#include <vector>
#include "Common/CommonTypes.h"
#ifdef _WIN32
#pragma warning(disable : 4786) // disable warning "identifier was truncated to
//'255' characters in the browser information"
#endif
typedef struct
{
std::string strDeviceName;
s32 iMajorVersion;
s32 iMinorVersion;
u32 uiSourceCount;
std::vector<std::string>* pvstrExtensions;
bool bSelected;
} ALDEVICEINFO, *LPALDEVICEINFO;
class ALDeviceList
{
private:
std::vector<ALDEVICEINFO> vDeviceInfo;
s32 defaultDeviceIndex;
s32 filterIndex;
public:
ALDeviceList();
~ALDeviceList();
s32 GetNumDevices();
char* GetDeviceName(s32 index);
void GetDeviceVersion(s32 index, s32* major, s32* minor);
u32 GetMaxNumSources(s32 index);
bool IsExtensionSupported(s32 index, char* szExtName);
s32 GetDefaultDevice();
void FilterDevicesMinVer(s32 major, s32 minor);
void FilterDevicesMaxVer(s32 major, s32 minor);
void FilterDevicesExtension(char* szExtName);
void ResetFilters();
s32 GetFirstFilteredDevice();
s32 GetNextFilteredDevice();
private:
u32 GetMaxNumSources();
};

View File

@ -43,7 +43,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;$(ExternalsDir)OpenAL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
@ -253,17 +253,14 @@
<ItemGroup>
<DataSysFiles Include="$(DolphinRootDir)Data\**\Sys\**\*.*" />
<DataTxtFiles Include="$(DolphinRootDir)Data\license.txt" />
<ExternalDlls Include="$(ExternalsDir)OpenAL\lib\*.dll" />
<BinaryFiles Include="$(TargetPath)" />
<AllInputFiles Include="@(DataSysFiles);@(DataTxtFiles);@(ExternalDlls);@(BinaryFiles)" />
<AllInputFiles Include="@(DataSysFiles);@(DataTxtFiles);@(BinaryFiles)" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="@(AllInputFiles)" Outputs="@(AllInputFiles -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)')">
<Message Text="Copying Data directory..." Importance="High" />
<Copy SourceFiles="@(DataSysFiles)" DestinationFolder="$(BinaryOutputDir)%(RecursiveDir)" Condition="!Exists('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)').Ticks)" />
<Copy SourceFiles="@(DataTxtFiles)" DestinationFolder="$(BinaryOutputDir)" Condition="!Exists('$(BinaryOutputDir)%(Filename)%(DataTxtFiles.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataTxtFiles.Extension)').Ticks)" />
<Message Text="Copying External .dlls" Importance="High" />
<Copy SourceFiles="@(ExternalDlls)" DestinationFolder="$(BinaryOutputDir)" Condition="!Exists('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)').Ticks)" />
<Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
</Target>
</Project>
</Project>

View File

@ -38,7 +38,7 @@
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<Link>
<AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;$(ExternalsDir)OpenAL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ResourceCompile>
@ -287,17 +287,14 @@
<ItemGroup>
<DataSysFiles Include="$(DolphinRootDir)Data\**\Sys\**\*.*" />
<DataTxtFiles Include="$(DolphinRootDir)Data\license.txt" />
<ExternalDlls Include="$(ExternalsDir)OpenAL\lib\*.dll" />
<BinaryFiles Include="$(TargetPath)" />
<AllInputFiles Include="@(DataSysFiles);@(DataTxtFiles);@(ExternalDlls);@(BinaryFiles)" />
<AllInputFiles Include="@(DataSysFiles);@(DataTxtFiles);@(BinaryFiles)" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="@(AllInputFiles)" Outputs="@(AllInputFiles -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)')">
<Message Text="Copying Data directory..." Importance="High" />
<Copy SourceFiles="@(DataSysFiles)" DestinationFolder="$(BinaryOutputDir)%(RecursiveDir)" Condition="!Exists('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)').Ticks)" />
<Copy SourceFiles="@(DataTxtFiles)" DestinationFolder="$(BinaryOutputDir)" Condition="!Exists('$(BinaryOutputDir)%(Filename)%(DataTxtFiles.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataTxtFiles.Extension)').Ticks)" />
<Message Text="Copying External .dlls" Importance="High" />
<Copy SourceFiles="@(ExternalDlls)" DestinationFolder="$(BinaryOutputDir)" Condition="!Exists('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)').Ticks)" />
<Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
</Target>
</Project>
</Project>

View File

@ -45,7 +45,7 @@
The following libs are needed since we pull in pretty much the entire
dolphin codebase.
-->
<AdditionalLibraryDirectories>$(ExternalsDir)OpenAL\lib;$(ExternalsDir)ffmpeg\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
@ -88,27 +88,8 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<!--
This project is always built, but the outputs are conditionally executed.
The tests will either be run by VS' test runner (requires a plugin to adapt
to gtest - developers will mostly use this method), or via msbuild (the
buildbot does it this way). The gtest adapter has the restriction that it
can only scan for tests on binaries it knows about (e.g. from projects' OutDir),
and it doesn't allow changing the working directory for running the tests.
Essentially this requires all runtime dependencies to be findable from the
context of the tests running with working directory set to OutDir. So...
that was the long-winded explanation of why we copy external things to the
OutDir :)
-->
<ItemGroup>
<ExternalDlls Include="$(ExternalsDir)OpenAL\lib\*.dll" />
</ItemGroup>
<!--Either method of running requires the runtime deps to be copied to pwd-->
<Target Name="CopyDeps" AfterTargets="AfterBuild" Inputs="@(ExternalDlls)" Outputs="@(ExternalDlls -> '$(OutDir)%(RecursiveDir)%(Filename)%(Extension)')">
<Copy SourceFiles="@(ExternalDlls)" DestinationFolder="$(OutDir)" Condition="!Exists('$(OutDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(OutDir)%(RecursiveDir)%(Filename)%(ExternalDlls.Extension)').Ticks)" />
</Target>
<Target Name="ExecUnitTests" AfterTargets="AfterBuild;CopyDeps" Condition="'$(RunUnitTests)'=='true'">
<!--This is only executed via msbuild, VS test runner automatically does this-->
<Exec Command="$(TargetPath)" />
</Target>
</Project>
</Project>

View File

@ -61,7 +61,6 @@
<PreprocessorDefinitions>SFML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>USE_ANALYTICS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>CURL_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_OPENAL=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!--
Make sure we include a clean version of windows.h.