mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 16:20:21 +00:00
Merge branch 'unplugged' into 'master'
Handle sound device changes Closes #4382 See merge request OpenMW/openmw!2791
This commit is contained in:
commit
88567cd363
@ -5,6 +5,7 @@
|
|||||||
Bug #3842: Body part skeletons override the main skeleton
|
Bug #3842: Body part skeletons override the main skeleton
|
||||||
Bug #4127: Weapon animation looks choppy
|
Bug #4127: Weapon animation looks choppy
|
||||||
Bug #4204: Dead slaughterfish doesn't float to water surface after loading saved game
|
Bug #4204: Dead slaughterfish doesn't float to water surface after loading saved game
|
||||||
|
Bug #4382: Sound output device does not change when it should
|
||||||
Bug #4610: Casting a Bound Weapon spell cancels the casting animation by equipping the weapon prematurely
|
Bug #4610: Casting a Bound Weapon spell cancels the casting animation by equipping the weapon prematurely
|
||||||
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
|
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
|
||||||
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
|
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
|
||||||
|
@ -1,38 +1,20 @@
|
|||||||
/**
|
|
||||||
* OpenAL cross platform audio library
|
|
||||||
* Copyright (C) 2008 by authors.
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Library General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
* Or go to https://www.gnu.org/copyleft/lgpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AL_ALEXT_H
|
#ifndef AL_ALEXT_H
|
||||||
#define AL_ALEXT_H
|
#define AL_ALEXT_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
/* Define int64_t and uint64_t types */
|
/* Define int64 and uint64 types */
|
||||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__cplusplus) && __cplusplus >= 201103L)
|
||||||
#include <inttypes.h>
|
|
||||||
#elif defined(_WIN32) && defined(__GNUC__)
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
typedef int64_t _alsoft_int64_t;
|
||||||
|
typedef uint64_t _alsoft_uint64_t;
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
typedef __int64 int64_t;
|
typedef __int64 _alsoft_int64_t;
|
||||||
typedef unsigned __int64 uint64_t;
|
typedef unsigned __int64 _alsoft_uint64_t;
|
||||||
#else
|
#else
|
||||||
/* Fallback if nothing above works */
|
/* Fallback if nothing above works */
|
||||||
#include <inttypes.h>
|
#include <stdint.h>
|
||||||
|
typedef int64_t _alsoft_int64_t;
|
||||||
|
typedef uint64_t _alsoft_uint64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "al.h"
|
#include "al.h"
|
||||||
@ -98,6 +80,31 @@ extern "C"
|
|||||||
|
|
||||||
#ifndef AL_EXT_MCFORMATS
|
#ifndef AL_EXT_MCFORMATS
|
||||||
#define AL_EXT_MCFORMATS 1
|
#define AL_EXT_MCFORMATS 1
|
||||||
|
/* Provides support for surround sound buffer formats with 8, 16, and 32-bit
|
||||||
|
* samples.
|
||||||
|
*
|
||||||
|
* QUAD8: Unsigned 8-bit, Quadraphonic (Front Left, Front Right, Rear Left,
|
||||||
|
* Rear Right).
|
||||||
|
* QUAD16: Signed 16-bit, Quadraphonic.
|
||||||
|
* QUAD32: 32-bit float, Quadraphonic.
|
||||||
|
* REAR8: Unsigned 8-bit, Rear Stereo (Rear Left, Rear Right).
|
||||||
|
* REAR16: Signed 16-bit, Rear Stereo.
|
||||||
|
* REAR32: 32-bit float, Rear Stereo.
|
||||||
|
* 51CHN8: Unsigned 8-bit, 5.1 Surround (Front Left, Front Right, Front Center,
|
||||||
|
* LFE, Side Left, Side Right). Note that some audio systems may label
|
||||||
|
* 5.1's Side channels as Rear or Surround; they are equivalent for the
|
||||||
|
* purposes of this extension.
|
||||||
|
* 51CHN16: Signed 16-bit, 5.1 Surround.
|
||||||
|
* 51CHN32: 32-bit float, 5.1 Surround.
|
||||||
|
* 61CHN8: Unsigned 8-bit, 6.1 Surround (Front Left, Front Right, Front Center,
|
||||||
|
* LFE, Rear Center, Side Left, Side Right).
|
||||||
|
* 61CHN16: Signed 16-bit, 6.1 Surround.
|
||||||
|
* 61CHN32: 32-bit float, 6.1 Surround.
|
||||||
|
* 71CHN8: Unsigned 8-bit, 7.1 Surround (Front Left, Front Right, Front Center,
|
||||||
|
* LFE, Rear Left, Rear Right, Side Left, Side Right).
|
||||||
|
* 71CHN16: Signed 16-bit, 7.1 Surround.
|
||||||
|
* 71CHN32: 32-bit float, 7.1 Surround.
|
||||||
|
*/
|
||||||
#define AL_FORMAT_QUAD8 0x1204
|
#define AL_FORMAT_QUAD8 0x1204
|
||||||
#define AL_FORMAT_QUAD16 0x1205
|
#define AL_FORMAT_QUAD16 0x1205
|
||||||
#define AL_FORMAT_QUAD32 0x1206
|
#define AL_FORMAT_QUAD32 0x1206
|
||||||
@ -134,9 +141,9 @@ extern "C"
|
|||||||
|
|
||||||
#ifndef AL_EXT_STATIC_BUFFER
|
#ifndef AL_EXT_STATIC_BUFFER
|
||||||
#define AL_EXT_STATIC_BUFFER 1
|
#define AL_EXT_STATIC_BUFFER 1
|
||||||
typedef ALvoid(AL_APIENTRY* PFNALBUFFERDATASTATICPROC)(const ALint, ALenum, ALvoid*, ALsizei, ALsizei);
|
typedef void(AL_APIENTRY* PFNALBUFFERDATASTATICPROC)(const ALint, ALenum, ALvoid*, ALsizei, ALsizei);
|
||||||
#ifdef AL_ALEXT_PROTOTYPES
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
AL_API ALvoid AL_APIENTRY alBufferDataStatic(
|
AL_API void AL_APIENTRY alBufferDataStatic(
|
||||||
const ALint buffer, ALenum format, ALvoid* data, ALsizei len, ALsizei freq);
|
const ALint buffer, ALenum format, ALvoid* data, ALsizei len, ALsizei freq);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -170,9 +177,9 @@ extern "C"
|
|||||||
#define AL_SOFT_buffer_sub_data 1
|
#define AL_SOFT_buffer_sub_data 1
|
||||||
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
|
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
|
||||||
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
|
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
|
||||||
typedef ALvoid(AL_APIENTRY* PFNALBUFFERSUBDATASOFTPROC)(ALuint, ALenum, const ALvoid*, ALsizei, ALsizei);
|
typedef void(AL_APIENTRY* PFNALBUFFERSUBDATASOFTPROC)(ALuint, ALenum, const ALvoid*, ALsizei, ALsizei);
|
||||||
#ifdef AL_ALEXT_PROTOTYPES
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(
|
AL_API void AL_APIENTRY alBufferSubDataSOFT(
|
||||||
ALuint buffer, ALenum format, const ALvoid* data, ALsizei offset, ALsizei length);
|
ALuint buffer, ALenum format, const ALvoid* data, ALsizei offset, ALsizei length);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -326,8 +333,8 @@ extern "C"
|
|||||||
#define AL_SOFT_source_latency 1
|
#define AL_SOFT_source_latency 1
|
||||||
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
|
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
|
||||||
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
|
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
|
||||||
typedef int64_t ALint64SOFT;
|
typedef _alsoft_int64_t ALint64SOFT;
|
||||||
typedef uint64_t ALuint64SOFT;
|
typedef _alsoft_uint64_t ALuint64SOFT;
|
||||||
typedef void(AL_APIENTRY* LPALSOURCEDSOFT)(ALuint, ALenum, ALdouble);
|
typedef void(AL_APIENTRY* LPALSOURCEDSOFT)(ALuint, ALenum, ALdouble);
|
||||||
typedef void(AL_APIENTRY* LPALSOURCE3DSOFT)(ALuint, ALenum, ALdouble, ALdouble, ALdouble);
|
typedef void(AL_APIENTRY* LPALSOURCE3DSOFT)(ALuint, ALenum, ALdouble, ALdouble, ALdouble);
|
||||||
typedef void(AL_APIENTRY* LPALSOURCEDVSOFT)(ALuint, ALenum, const ALdouble*);
|
typedef void(AL_APIENTRY* LPALSOURCEDVSOFT)(ALuint, ALenum, const ALdouble*);
|
||||||
@ -368,11 +375,11 @@ extern "C"
|
|||||||
#ifndef AL_SOFT_deferred_updates
|
#ifndef AL_SOFT_deferred_updates
|
||||||
#define AL_SOFT_deferred_updates 1
|
#define AL_SOFT_deferred_updates 1
|
||||||
#define AL_DEFERRED_UPDATES_SOFT 0xC002
|
#define AL_DEFERRED_UPDATES_SOFT 0xC002
|
||||||
typedef ALvoid(AL_APIENTRY* LPALDEFERUPDATESSOFT)(void);
|
typedef void(AL_APIENTRY* LPALDEFERUPDATESSOFT)(void);
|
||||||
typedef ALvoid(AL_APIENTRY* LPALPROCESSUPDATESSOFT)(void);
|
typedef void(AL_APIENTRY* LPALPROCESSUPDATESSOFT)(void);
|
||||||
#ifdef AL_ALEXT_PROTOTYPES
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
|
AL_API void AL_APIENTRY alDeferUpdatesSOFT(void);
|
||||||
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
|
AL_API void AL_APIENTRY alProcessUpdatesSOFT(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -407,6 +414,16 @@ extern "C"
|
|||||||
|
|
||||||
#ifndef AL_EXT_BFORMAT
|
#ifndef AL_EXT_BFORMAT
|
||||||
#define AL_EXT_BFORMAT 1
|
#define AL_EXT_BFORMAT 1
|
||||||
|
/* Provides support for B-Format ambisonic buffers (first-order, FuMa scaling
|
||||||
|
* and layout).
|
||||||
|
*
|
||||||
|
* BFORMAT2D_8: Unsigned 8-bit, 3-channel non-periphonic (WXY).
|
||||||
|
* BFORMAT2D_16: Signed 16-bit, 3-channel non-periphonic (WXY).
|
||||||
|
* BFORMAT2D_FLOAT32: 32-bit float, 3-channel non-periphonic (WXY).
|
||||||
|
* BFORMAT3D_8: Unsigned 8-bit, 4-channel periphonic (WXYZ).
|
||||||
|
* BFORMAT3D_16: Signed 16-bit, 4-channel periphonic (WXYZ).
|
||||||
|
* BFORMAT3D_FLOAT32: 32-bit float, 4-channel periphonic (WXYZ).
|
||||||
|
*/
|
||||||
#define AL_FORMAT_BFORMAT2D_8 0x20021
|
#define AL_FORMAT_BFORMAT2D_8 0x20021
|
||||||
#define AL_FORMAT_BFORMAT2D_16 0x20022
|
#define AL_FORMAT_BFORMAT2D_16 0x20022
|
||||||
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
|
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
|
||||||
@ -471,6 +488,152 @@ extern "C"
|
|||||||
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
|
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALC_SOFT_device_clock
|
||||||
|
#define ALC_SOFT_device_clock 1
|
||||||
|
typedef _alsoft_int64_t ALCint64SOFT;
|
||||||
|
typedef _alsoft_uint64_t ALCuint64SOFT;
|
||||||
|
#define ALC_DEVICE_CLOCK_SOFT 0x1600
|
||||||
|
#define ALC_DEVICE_LATENCY_SOFT 0x1601
|
||||||
|
#define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602
|
||||||
|
#define AL_SAMPLE_OFFSET_CLOCK_SOFT 0x1202
|
||||||
|
#define AL_SEC_OFFSET_CLOCK_SOFT 0x1203
|
||||||
|
typedef void(ALC_APIENTRY* LPALCGETINTEGER64VSOFT)(
|
||||||
|
ALCdevice* device, ALCenum pname, ALsizei size, ALCint64SOFT* values);
|
||||||
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
|
ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(
|
||||||
|
ALCdevice* device, ALCenum pname, ALsizei size, ALCint64SOFT* values);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_direct_channels_remix
|
||||||
|
#define AL_SOFT_direct_channels_remix 1
|
||||||
|
#define AL_DROP_UNMATCHED_SOFT 0x0001
|
||||||
|
#define AL_REMIX_UNMATCHED_SOFT 0x0002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_bformat_ex
|
||||||
|
#define AL_SOFT_bformat_ex 1
|
||||||
|
#define AL_AMBISONIC_LAYOUT_SOFT 0x1997
|
||||||
|
#define AL_AMBISONIC_SCALING_SOFT 0x1998
|
||||||
|
|
||||||
|
/* Ambisonic layouts */
|
||||||
|
#define AL_FUMA_SOFT 0x0000
|
||||||
|
#define AL_ACN_SOFT 0x0001
|
||||||
|
|
||||||
|
/* Ambisonic scalings (normalization) */
|
||||||
|
/*#define AL_FUMA_SOFT*/
|
||||||
|
#define AL_SN3D_SOFT 0x0001
|
||||||
|
#define AL_N3D_SOFT 0x0002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALC_SOFT_loopback_bformat
|
||||||
|
#define ALC_SOFT_loopback_bformat 1
|
||||||
|
#define ALC_AMBISONIC_LAYOUT_SOFT 0x1997
|
||||||
|
#define ALC_AMBISONIC_SCALING_SOFT 0x1998
|
||||||
|
#define ALC_AMBISONIC_ORDER_SOFT 0x1999
|
||||||
|
#define ALC_MAX_AMBISONIC_ORDER_SOFT 0x199B
|
||||||
|
|
||||||
|
#define ALC_BFORMAT3D_SOFT 0x1507
|
||||||
|
|
||||||
|
/* Ambisonic layouts */
|
||||||
|
#define ALC_FUMA_SOFT 0x0000
|
||||||
|
#define ALC_ACN_SOFT 0x0001
|
||||||
|
|
||||||
|
/* Ambisonic scalings (normalization) */
|
||||||
|
/*#define ALC_FUMA_SOFT*/
|
||||||
|
#define ALC_SN3D_SOFT 0x0001
|
||||||
|
#define ALC_N3D_SOFT 0x0002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_effect_target
|
||||||
|
#define AL_SOFT_effect_target
|
||||||
|
#define AL_EFFECTSLOT_TARGET_SOFT 0x199C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_events
|
||||||
|
#define AL_SOFT_events 1
|
||||||
|
#define AL_EVENT_CALLBACK_FUNCTION_SOFT 0x19A2
|
||||||
|
#define AL_EVENT_CALLBACK_USER_PARAM_SOFT 0x19A3
|
||||||
|
#define AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT 0x19A4
|
||||||
|
#define AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT 0x19A5
|
||||||
|
#define AL_EVENT_TYPE_DISCONNECTED_SOFT 0x19A6
|
||||||
|
typedef void(AL_APIENTRY* ALEVENTPROCSOFT)(
|
||||||
|
ALenum eventType, ALuint object, ALuint param, ALsizei length, const ALchar* message, void* userParam);
|
||||||
|
typedef void(AL_APIENTRY* LPALEVENTCONTROLSOFT)(ALsizei count, const ALenum* types, ALboolean enable);
|
||||||
|
typedef void(AL_APIENTRY* LPALEVENTCALLBACKSOFT)(ALEVENTPROCSOFT callback, void* userParam);
|
||||||
|
typedef void*(AL_APIENTRY* LPALGETPOINTERSOFT)(ALenum pname);
|
||||||
|
typedef void(AL_APIENTRY* LPALGETPOINTERVSOFT)(ALenum pname, void** values);
|
||||||
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
|
AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum* types, ALboolean enable);
|
||||||
|
AL_API void AL_APIENTRY alEventCallbackSOFT(ALEVENTPROCSOFT callback, void* userParam);
|
||||||
|
AL_API void* AL_APIENTRY alGetPointerSOFT(ALenum pname);
|
||||||
|
AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void** values);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALC_SOFT_reopen_device
|
||||||
|
#define ALC_SOFT_reopen_device
|
||||||
|
typedef ALCboolean(ALC_APIENTRY* LPALCREOPENDEVICESOFT)(
|
||||||
|
ALCdevice* device, const ALCchar* deviceName, const ALCint* attribs);
|
||||||
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
|
ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice* device, const ALCchar* deviceName, const ALCint* attribs);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_callback_buffer
|
||||||
|
#define AL_SOFT_callback_buffer
|
||||||
|
#define AL_BUFFER_CALLBACK_FUNCTION_SOFT 0x19A0
|
||||||
|
#define AL_BUFFER_CALLBACK_USER_PARAM_SOFT 0x19A1
|
||||||
|
typedef ALsizei(AL_APIENTRY* ALBUFFERCALLBACKTYPESOFT)(ALvoid* userptr, ALvoid* sampledata, ALsizei numbytes);
|
||||||
|
typedef void(AL_APIENTRY* LPALBUFFERCALLBACKSOFT)(
|
||||||
|
ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid* userptr);
|
||||||
|
typedef void(AL_APIENTRY* LPALGETBUFFERPTRSOFT)(ALuint buffer, ALenum param, ALvoid** value);
|
||||||
|
typedef void(AL_APIENTRY* LPALGETBUFFER3PTRSOFT)(
|
||||||
|
ALuint buffer, ALenum param, ALvoid** value1, ALvoid** value2, ALvoid** value3);
|
||||||
|
typedef void(AL_APIENTRY* LPALGETBUFFERPTRVSOFT)(ALuint buffer, ALenum param, ALvoid** values);
|
||||||
|
#ifdef AL_ALEXT_PROTOTYPES
|
||||||
|
AL_API void AL_APIENTRY alBufferCallbackSOFT(
|
||||||
|
ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid* userptr);
|
||||||
|
AL_API void AL_APIENTRY alGetBufferPtrSOFT(ALuint buffer, ALenum param, ALvoid** ptr);
|
||||||
|
AL_API void AL_APIENTRY alGetBuffer3PtrSOFT(
|
||||||
|
ALuint buffer, ALenum param, ALvoid** ptr0, ALvoid** ptr1, ALvoid** ptr2);
|
||||||
|
AL_API void AL_APIENTRY alGetBufferPtrvSOFT(ALuint buffer, ALenum param, ALvoid** ptr);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_UHJ
|
||||||
|
#define AL_SOFT_UHJ
|
||||||
|
#define AL_FORMAT_UHJ2CHN8_SOFT 0x19A2
|
||||||
|
#define AL_FORMAT_UHJ2CHN16_SOFT 0x19A3
|
||||||
|
#define AL_FORMAT_UHJ2CHN_FLOAT32_SOFT 0x19A4
|
||||||
|
#define AL_FORMAT_UHJ3CHN8_SOFT 0x19A5
|
||||||
|
#define AL_FORMAT_UHJ3CHN16_SOFT 0x19A6
|
||||||
|
#define AL_FORMAT_UHJ3CHN_FLOAT32_SOFT 0x19A7
|
||||||
|
#define AL_FORMAT_UHJ4CHN8_SOFT 0x19A8
|
||||||
|
#define AL_FORMAT_UHJ4CHN16_SOFT 0x19A9
|
||||||
|
#define AL_FORMAT_UHJ4CHN_FLOAT32_SOFT 0x19AA
|
||||||
|
|
||||||
|
#define AL_STEREO_MODE_SOFT 0x19B0
|
||||||
|
#define AL_NORMAL_SOFT 0x0000
|
||||||
|
#define AL_SUPER_STEREO_SOFT 0x0001
|
||||||
|
#define AL_SUPER_STEREO_WIDTH_SOFT 0x19B1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALC_SOFT_output_mode
|
||||||
|
#define ALC_SOFT_output_mode
|
||||||
|
#define ALC_OUTPUT_MODE_SOFT 0x19AC
|
||||||
|
#define ALC_ANY_SOFT 0x19AD
|
||||||
|
/*#define ALC_MONO_SOFT 0x1500*/
|
||||||
|
/*#define ALC_STEREO_SOFT 0x1501*/
|
||||||
|
#define ALC_STEREO_BASIC_SOFT 0x19AE
|
||||||
|
#define ALC_STEREO_UHJ_SOFT 0x19AF
|
||||||
|
#define ALC_STEREO_HRTF_SOFT 0x19B2
|
||||||
|
/*#define ALC_QUAD_SOFT 0x1503*/
|
||||||
|
#define ALC_SURROUND_5_1_SOFT 0x1504
|
||||||
|
#define ALC_SURROUND_6_1_SOFT 0x1505
|
||||||
|
#define ALC_SURROUND_7_1_SOFT 0x1506
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/misc/thread.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
#include "loudness.hpp"
|
#include "loudness.hpp"
|
||||||
@ -112,6 +114,10 @@ namespace
|
|||||||
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
||||||
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
||||||
|
|
||||||
|
LPALEVENTCONTROLSOFT alEventControlSOFT;
|
||||||
|
LPALEVENTCALLBACKSOFT alEventCallbackSOFT;
|
||||||
|
LPALCREOPENDEVICESOFT alcReopenDeviceSOFT;
|
||||||
|
|
||||||
void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES& props)
|
void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES& props)
|
||||||
{
|
{
|
||||||
ALint type = AL_NONE;
|
ALint type = AL_NONE;
|
||||||
@ -161,6 +167,17 @@ namespace
|
|||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::basic_string_view<ALCchar> getDeviceName(ALCdevice* device)
|
||||||
|
{
|
||||||
|
const ALCchar* name = nullptr;
|
||||||
|
if (alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT"))
|
||||||
|
name = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
|
||||||
|
if (alcGetError(device) != AL_NO_ERROR || !name)
|
||||||
|
name = alcGetString(device, ALC_DEVICE_SPECIFIER);
|
||||||
|
if (name == nullptr) // Prevent assigning nullptr to std::string
|
||||||
|
return {};
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
@ -310,8 +327,7 @@ namespace MWSound
|
|||||||
//
|
//
|
||||||
struct OpenAL_Output::StreamThread
|
struct OpenAL_Output::StreamThread
|
||||||
{
|
{
|
||||||
typedef std::vector<OpenAL_SoundStream*> StreamVec;
|
std::vector<OpenAL_SoundStream*> mStreams;
|
||||||
StreamVec mStreams;
|
|
||||||
|
|
||||||
std::atomic<bool> mQuitNow;
|
std::atomic<bool> mQuitNow;
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
@ -338,7 +354,7 @@ namespace MWSound
|
|||||||
std::unique_lock<std::mutex> lock(mMutex);
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
while (!mQuitNow)
|
while (!mQuitNow)
|
||||||
{
|
{
|
||||||
StreamVec::iterator iter = mStreams.begin();
|
auto iter = mStreams.begin();
|
||||||
while (iter != mStreams.end())
|
while (iter != mStreams.end())
|
||||||
{
|
{
|
||||||
if ((*iter)->process() == false)
|
if ((*iter)->process() == false)
|
||||||
@ -364,7 +380,7 @@ namespace MWSound
|
|||||||
void remove(OpenAL_SoundStream* stream)
|
void remove(OpenAL_SoundStream* stream)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
StreamVec::iterator iter = std::find(mStreams.begin(), mStreams.end(), stream);
|
auto iter = std::find(mStreams.begin(), mStreams.end(), stream);
|
||||||
if (iter != mStreams.end())
|
if (iter != mStreams.end())
|
||||||
mStreams.erase(iter);
|
mStreams.erase(iter);
|
||||||
}
|
}
|
||||||
@ -375,9 +391,70 @@ namespace MWSound
|
|||||||
mStreams.clear();
|
mStreams.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamThread(const StreamThread& rhs) = delete;
|
||||||
|
StreamThread& operator=(const StreamThread& rhs) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenAL_Output::DefaultDeviceThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::basic_string<ALCchar> mCurrentName;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StreamThread(const StreamThread& rhs);
|
OpenAL_Output& mOutput;
|
||||||
StreamThread& operator=(const StreamThread& rhs);
|
|
||||||
|
std::atomic<bool> mQuitNow;
|
||||||
|
std::mutex mMutex;
|
||||||
|
std::condition_variable mCondVar;
|
||||||
|
std::thread mThread;
|
||||||
|
|
||||||
|
DefaultDeviceThread(const DefaultDeviceThread&) = delete;
|
||||||
|
DefaultDeviceThread& operator=(const DefaultDeviceThread&) = delete;
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
Misc::setCurrentThreadIdlePriority();
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
|
while (!mQuitNow)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> openLock(mOutput.mReopenMutex);
|
||||||
|
auto defaultName = getDeviceName(nullptr);
|
||||||
|
if (mCurrentName != defaultName)
|
||||||
|
{
|
||||||
|
Log(Debug::Info) << "Default audio device changed";
|
||||||
|
ALCboolean reopened
|
||||||
|
= alcReopenDeviceSOFT(mOutput.mDevice, nullptr, mOutput.mContextAttributes.data());
|
||||||
|
if (reopened == AL_FALSE)
|
||||||
|
{
|
||||||
|
mCurrentName = defaultName;
|
||||||
|
Log(Debug::Warning) << "Failed to switch to new audio device";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mCurrentName = getDeviceName(mOutput.mDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCondVar.wait_for(lock, std::chrono::seconds(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DefaultDeviceThread(OpenAL_Output& output, std::basic_string_view<ALCchar> name = {})
|
||||||
|
: mCurrentName(name)
|
||||||
|
, mOutput(output)
|
||||||
|
, mQuitNow(false)
|
||||||
|
, mThread([this] { run(); })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~DefaultDeviceThread()
|
||||||
|
{
|
||||||
|
mQuitNow = true;
|
||||||
|
mMutex.lock();
|
||||||
|
mMutex.unlock();
|
||||||
|
mCondVar.notify_all();
|
||||||
|
mThread.join();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenAL_SoundStream::OpenAL_SoundStream(ALuint src, DecoderPtr decoder)
|
OpenAL_SoundStream::OpenAL_SoundStream(ALuint src, DecoderPtr decoder)
|
||||||
@ -601,17 +678,50 @@ namespace MWSound
|
|||||||
return devlist;
|
return devlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenAL_Output::eventCallback(
|
||||||
|
ALenum eventType, ALuint object, ALuint param, ALsizei length, const ALchar* message, void* userParam)
|
||||||
|
{
|
||||||
|
if (eventType == AL_EVENT_TYPE_DISCONNECTED_SOFT)
|
||||||
|
static_cast<OpenAL_Output*>(userParam)->onDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenAL_Output::onDisconnect()
|
||||||
|
{
|
||||||
|
if (!mInitialized || !alcReopenDeviceSOFT)
|
||||||
|
return;
|
||||||
|
const std::lock_guard<std::mutex> lock(mReopenMutex);
|
||||||
|
Log(Debug::Warning) << "Audio device disconnected, attempting to reopen...";
|
||||||
|
ALCboolean reopened = alcReopenDeviceSOFT(mDevice, mDeviceName.c_str(), mContextAttributes.data());
|
||||||
|
if (reopened == AL_FALSE && !mDeviceName.empty())
|
||||||
|
{
|
||||||
|
reopened = alcReopenDeviceSOFT(mDevice, nullptr, mContextAttributes.data());
|
||||||
|
if (reopened == AL_TRUE && !mDefaultDeviceThread)
|
||||||
|
mDefaultDeviceThread = std::make_unique<DefaultDeviceThread>(*this);
|
||||||
|
}
|
||||||
|
if (reopened == AL_FALSE)
|
||||||
|
Log(Debug::Error) << "Failed to reopen audio device";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Debug::Info) << "Reopened audio device";
|
||||||
|
if (mDefaultDeviceThread)
|
||||||
|
mDefaultDeviceThread->mCurrentName = getDeviceName(mDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool OpenAL_Output::init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode)
|
bool OpenAL_Output::init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode)
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(mReopenMutex);
|
||||||
deinit();
|
deinit();
|
||||||
|
|
||||||
Log(Debug::Info) << "Initializing OpenAL...";
|
Log(Debug::Info) << "Initializing OpenAL...";
|
||||||
|
|
||||||
|
mDeviceName = devname;
|
||||||
mDevice = alcOpenDevice(devname.c_str());
|
mDevice = alcOpenDevice(devname.c_str());
|
||||||
if (!mDevice && !devname.empty())
|
if (!mDevice && !devname.empty())
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Failed to open \"" << devname << "\", trying default";
|
Log(Debug::Warning) << "Failed to open \"" << devname << "\", trying default";
|
||||||
mDevice = alcOpenDevice(nullptr);
|
mDevice = alcOpenDevice(nullptr);
|
||||||
|
mDeviceName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDevice)
|
if (!mDevice)
|
||||||
@ -620,11 +730,7 @@ namespace MWSound
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALCchar* name = nullptr;
|
auto name = getDeviceName(mDevice);
|
||||||
if (alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT"))
|
|
||||||
name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER);
|
|
||||||
if (alcGetError(mDevice) != AL_NO_ERROR || !name)
|
|
||||||
name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER);
|
|
||||||
Log(Debug::Info) << "Opened \"" << name << "\"";
|
Log(Debug::Info) << "Opened \"" << name << "\"";
|
||||||
|
|
||||||
ALCint major = 0, minor = 0;
|
ALCint major = 0, minor = 0;
|
||||||
@ -636,17 +742,17 @@ namespace MWSound
|
|||||||
ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX");
|
ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX");
|
||||||
ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF");
|
ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF");
|
||||||
|
|
||||||
std::vector<ALCint> attrs;
|
mContextAttributes.clear();
|
||||||
attrs.reserve(15);
|
mContextAttributes.reserve(15);
|
||||||
if (ALC.SOFT_HRTF)
|
if (ALC.SOFT_HRTF)
|
||||||
{
|
{
|
||||||
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
|
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
|
||||||
getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT");
|
getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT");
|
||||||
|
|
||||||
attrs.push_back(ALC_HRTF_SOFT);
|
mContextAttributes.push_back(ALC_HRTF_SOFT);
|
||||||
attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE
|
mContextAttributes.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE
|
||||||
: hrtfmode == HrtfMode::Enable ? ALC_TRUE
|
: hrtfmode == HrtfMode::Enable ? ALC_TRUE
|
||||||
:
|
:
|
||||||
/*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT);
|
/*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT);
|
||||||
if (!hrtfname.empty())
|
if (!hrtfname.empty())
|
||||||
{
|
{
|
||||||
@ -667,14 +773,14 @@ namespace MWSound
|
|||||||
Log(Debug::Warning) << "Failed to find HRTF \"" << hrtfname << "\", using default";
|
Log(Debug::Warning) << "Failed to find HRTF \"" << hrtfname << "\", using default";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
attrs.push_back(ALC_HRTF_ID_SOFT);
|
mContextAttributes.push_back(ALC_HRTF_ID_SOFT);
|
||||||
attrs.push_back(index);
|
mContextAttributes.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attrs.push_back(0);
|
mContextAttributes.push_back(0);
|
||||||
|
|
||||||
mContext = alcCreateContext(mDevice, attrs.data());
|
mContext = alcCreateContext(mDevice, mContextAttributes.data());
|
||||||
if (!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
if (!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Failed to setup audio context: " << alcGetString(mDevice, alcGetError(mDevice));
|
Log(Debug::Error) << "Failed to setup audio context: " << alcGetString(mDevice, alcGetError(mDevice));
|
||||||
@ -691,6 +797,30 @@ namespace MWSound
|
|||||||
<< " Version: " << alGetString(AL_VERSION) << "\n"
|
<< " Version: " << alGetString(AL_VERSION) << "\n"
|
||||||
<< " Extensions: " << alGetString(AL_EXTENSIONS);
|
<< " Extensions: " << alGetString(AL_EXTENSIONS);
|
||||||
|
|
||||||
|
if (alIsExtensionPresent("AL_SOFT_events"))
|
||||||
|
{
|
||||||
|
getALFunc(alEventControlSOFT, "alEventControlSOFT");
|
||||||
|
getALFunc(alEventCallbackSOFT, "alEventCallbackSOFT");
|
||||||
|
}
|
||||||
|
if (alcIsExtensionPresent(mDevice, "ALC_SOFT_reopen_device"))
|
||||||
|
getALFunc(alcReopenDeviceSOFT, "alcReopenDeviceSOFT");
|
||||||
|
if (alEventControlSOFT)
|
||||||
|
{
|
||||||
|
static const std::array<ALenum, 1> events{ { AL_EVENT_TYPE_DISCONNECTED_SOFT } };
|
||||||
|
alEventControlSOFT(events.size(), events.data(), AL_TRUE);
|
||||||
|
alEventCallbackSOFT(&OpenAL_Output::eventCallback, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log(Debug::Warning) << "Cannot detect audio device changes";
|
||||||
|
if (mDeviceName.empty() && !name.empty())
|
||||||
|
{
|
||||||
|
// If we opened the default device, switch devices if a new default is selected
|
||||||
|
if (alcReopenDeviceSOFT)
|
||||||
|
mDefaultDeviceThread = std::make_unique<DefaultDeviceThread>(*this, name);
|
||||||
|
else
|
||||||
|
Log(Debug::Warning) << "Cannot switch audio devices if the default changes";
|
||||||
|
}
|
||||||
|
|
||||||
if (!ALC.SOFT_HRTF)
|
if (!ALC.SOFT_HRTF)
|
||||||
Log(Debug::Warning) << "HRTF status unavailable";
|
Log(Debug::Warning) << "HRTF status unavailable";
|
||||||
else
|
else
|
||||||
@ -849,6 +979,7 @@ namespace MWSound
|
|||||||
void OpenAL_Output::deinit()
|
void OpenAL_Output::deinit()
|
||||||
{
|
{
|
||||||
mStreamThread->removeAll();
|
mStreamThread->removeAll();
|
||||||
|
mDefaultDeviceThread.release();
|
||||||
|
|
||||||
for (ALuint source : mFreeSources)
|
for (ALuint source : mFreeSources)
|
||||||
alDeleteSources(1, &source);
|
alDeleteSources(1, &source);
|
||||||
@ -867,6 +998,9 @@ namespace MWSound
|
|||||||
alDeleteFilters(1, &mWaterFilter);
|
alDeleteFilters(1, &mWaterFilter);
|
||||||
mWaterFilter = 0;
|
mWaterFilter = 0;
|
||||||
|
|
||||||
|
if (alEventCallbackSOFT)
|
||||||
|
alEventCallbackSOFT(nullptr, nullptr);
|
||||||
|
|
||||||
alcMakeContextCurrent(nullptr);
|
alcMakeContextCurrent(nullptr);
|
||||||
if (mContext)
|
if (mContext)
|
||||||
alcDestroyContext(mContext);
|
alcDestroyContext(mContext);
|
||||||
@ -1526,6 +1660,7 @@ namespace MWSound
|
|||||||
|
|
||||||
OpenAL_Output::~OpenAL_Output()
|
OpenAL_Output::~OpenAL_Output()
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(mReopenMutex);
|
||||||
OpenAL_Output::deinit();
|
OpenAL_Output::deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -53,6 +54,13 @@ namespace MWSound
|
|||||||
struct StreamThread;
|
struct StreamThread;
|
||||||
std::unique_ptr<StreamThread> mStreamThread;
|
std::unique_ptr<StreamThread> mStreamThread;
|
||||||
|
|
||||||
|
std::string mDeviceName;
|
||||||
|
std::vector<ALCint> mContextAttributes;
|
||||||
|
std::mutex mReopenMutex;
|
||||||
|
|
||||||
|
class DefaultDeviceThread;
|
||||||
|
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
||||||
|
|
||||||
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||||
void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
||||||
ALfloat pitch, bool loop, bool useenv);
|
ALfloat pitch, bool loop, bool useenv);
|
||||||
@ -65,6 +73,11 @@ namespace MWSound
|
|||||||
OpenAL_Output& operator=(const OpenAL_Output& rhs);
|
OpenAL_Output& operator=(const OpenAL_Output& rhs);
|
||||||
OpenAL_Output(const OpenAL_Output& rhs);
|
OpenAL_Output(const OpenAL_Output& rhs);
|
||||||
|
|
||||||
|
static void eventCallback(
|
||||||
|
ALenum eventType, ALuint object, ALuint param, ALsizei length, const ALchar* message, void* userParam);
|
||||||
|
|
||||||
|
void onDisconnect();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<std::string> enumerate() override;
|
std::vector<std::string> enumerate() override;
|
||||||
bool init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode) override;
|
bool init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode) override;
|
||||||
|
@ -79,7 +79,7 @@ namespace MWSound
|
|||||||
|
|
||||||
SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound)
|
SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound)
|
||||||
: mVFS(vfs)
|
: mVFS(vfs)
|
||||||
, mOutput(new OpenAL_Output(*this))
|
, mOutput(std::make_unique<OpenAL_Output>(*this))
|
||||||
, mWaterSoundUpdater(makeWaterSoundUpdaterSettings())
|
, mWaterSoundUpdater(makeWaterSoundUpdaterSettings())
|
||||||
, mSoundBuffers(*vfs, *mOutput)
|
, mSoundBuffers(*vfs, *mOutput)
|
||||||
, mListenerUnderwater(false)
|
, mListenerUnderwater(false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user