Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/extern
diff options
context:
space:
mode:
authorJörg Müller <nexyon@gmail.com>2022-01-15 00:51:35 +0300
committerJörg Müller <nexyon@gmail.com>2022-01-15 00:51:35 +0300
commit2a095d8bfee39cb6f7f4f108d7febf9780bb8241 (patch)
tree4d9c7e282428f4ed8c0ae296c396bced8a1c6913 /extern
parent9fe704800ef1288ef7258e9dda6a538dc92ddddd (diff)
Audaspace: port bugfixes from upstream.
Windows audio backend (WASAPI) now automatically switches to the selected audio device in windows.
Diffstat (limited to 'extern')
-rw-r--r--extern/audaspace/CMakeLists.txt6
-rw-r--r--extern/audaspace/bindings/python/setup.py.in27
-rw-r--r--extern/audaspace/plugins/wasapi/WASAPIDevice.cpp80
-rw-r--r--extern/audaspace/plugins/wasapi/WASAPIDevice.h15
4 files changed, 109 insertions, 19 deletions
diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt
index 8493fe3e67d..9877c8f7768 100644
--- a/extern/audaspace/CMakeLists.txt
+++ b/extern/audaspace/CMakeLists.txt
@@ -1092,12 +1092,12 @@ if(WITH_PYTHON)
configure_file(${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py ESCAPE_QUOTES @ONLY)
if(APPLE)
- add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
elseif(WIN32)
set(ENV{VS100COMNTOOLS} $ENV{VS120COMNTOOLS})
- add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
else()
- add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
endif()
add_custom_target(pythonmodule ALL DEPENDS build SOURCES ${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${PYTHON_SRC} ${PYTHON_HDR})
add_dependencies(pythonmodule audaspace)
diff --git a/extern/audaspace/bindings/python/setup.py.in b/extern/audaspace/bindings/python/setup.py.in
index 5ad1a37db3a..0e6666e06a0 100644
--- a/extern/audaspace/bindings/python/setup.py.in
+++ b/extern/audaspace/bindings/python/setup.py.in
@@ -8,20 +8,20 @@ import numpy
from distutils.core import setup, Extension
if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
- import subprocess
- from distutils.core import Distribution
- from distutils.command.build import build
+ import subprocess
+ from distutils.core import Distribution
+ from distutils.command.build import build
- dist = Distribution()
- cmd = build(dist)
- cmd.finalize_options()
- #print(cmd.build_platlib)
+ dist = Distribution()
+ cmd = build(dist)
+ cmd.finalize_options()
+ #print(cmd.build_platlib)
- os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
- os.environ['LD_LIBRARY_PATH'] = os.getcwd()
+ os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
+ os.environ['LD_LIBRARY_PATH'] = os.getcwd()
- ret = subprocess.call(sys.argv[2:])
- sys.exit(ret)
+ ret = subprocess.call(sys.argv[2:])
+ sys.exit(ret)
# the following line is not working due to https://bugs.python.org/issue9023
@@ -43,7 +43,8 @@ audaspace = Extension(
library_dirs = ['.', 'Release', 'Debug'],
language = 'c++',
extra_compile_args = extra_args,
- sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
+ define_macros = [('WITH_CONVOLUTION', None)] if '@WITH_FFTW@' == 'ON' else [],
+ sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
)
setup(
@@ -56,6 +57,6 @@ setup(
license = 'Apache License 2.0',
long_description = codecs.open(os.path.join(source_directory, '../../README.md'), 'r', 'utf-8').read(),
ext_modules = [audaspace],
- headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
+ headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
)
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
index a5382bb9692..a8387dd9489 100644
--- a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
+++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
@@ -95,6 +95,13 @@ void WASAPIDevice::runMixingThread()
sleep_duration = std::chrono::milliseconds(buffer_size * 1000 / int(m_specs.rate) / 2);
}
+ if(m_default_device_changed)
+ {
+ m_default_device_changed = false;
+ result = AUDCLNT_E_DEVICE_INVALIDATED;
+ goto stop_thread;
+ }
+
if(FAILED(result = m_audio_client->GetCurrentPadding(&padding)))
goto stop_thread;
@@ -296,13 +303,78 @@ bool WASAPIDevice::setupDevice(DeviceSpecs &specs)
return true;
}
+ULONG WASAPIDevice::AddRef()
+{
+ return InterlockedIncrement(&m_reference_count);
+}
+
+ULONG WASAPIDevice::Release()
+{
+ ULONG reference_count = InterlockedDecrement(&m_reference_count);
+
+ if(0 == reference_count)
+ delete this;
+
+ return reference_count;
+}
+
+HRESULT WASAPIDevice::QueryInterface(REFIID riid, void **ppvObject)
+{
+ if(riid == __uuidof(IMMNotificationClient))
+ {
+ *ppvObject = reinterpret_cast<IMMNotificationClient*>(this);
+ AddRef();
+ }
+ else if(riid == IID_IUnknown)
+ {
+ *ppvObject = reinterpret_cast<IUnknown*>(this);
+ AddRef();
+ }
+ else
+ {
+ *ppvObject = nullptr;
+ return E_NOINTERFACE;
+ }
+
+ return S_OK;
+}
+
+HRESULT WASAPIDevice::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
+{
+ return S_OK;
+}
+
+HRESULT WASAPIDevice::OnDeviceAdded(LPCWSTR pwstrDeviceId)
+{
+ return S_OK;
+}
+
+HRESULT WASAPIDevice::OnDeviceRemoved(LPCWSTR pwstrDeviceId)
+{
+ return S_OK;
+}
+
+HRESULT WASAPIDevice::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
+{
+ if(flow != EDataFlow::eCapture)
+ m_default_device_changed = true;
+
+ return S_OK;
+}
+
+HRESULT WASAPIDevice::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
+{
+ return S_OK;
+}
+
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
m_buffersize(buffersize),
m_imm_device_enumerator(nullptr),
m_imm_device(nullptr),
m_audio_client(nullptr),
-
- m_wave_format_extensible({})
+ m_wave_format_extensible({}),
+ m_default_device_changed(false),
+ m_reference_count(1)
{
// initialize COM if it hasn't happened yet
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
@@ -327,6 +399,8 @@ WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
create();
+ m_imm_device_enumerator->RegisterEndpointNotificationCallback(this);
+
return;
error:
@@ -340,6 +414,8 @@ WASAPIDevice::~WASAPIDevice()
{
stopMixingThread();
+ m_imm_device_enumerator->UnregisterEndpointNotificationCallback(this);
+
SafeRelease(&m_audio_client);
SafeRelease(&m_imm_device);
SafeRelease(&m_imm_device_enumerator);
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.h b/extern/audaspace/plugins/wasapi/WASAPIDevice.h
index 3b11adc98ef..24d0fedc191 100644
--- a/extern/audaspace/plugins/wasapi/WASAPIDevice.h
+++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.h
@@ -40,7 +40,7 @@ AUD_NAMESPACE_BEGIN
/**
* This device plays back through WASAPI, the Windows audio API.
*/
-class AUD_PLUGIN_API WASAPIDevice : public ThreadedDevice
+class AUD_PLUGIN_API WASAPIDevice : IMMNotificationClient, public ThreadedDevice
{
private:
int m_buffersize;
@@ -48,6 +48,8 @@ private:
IMMDevice* m_imm_device;
IAudioClient* m_audio_client;
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
+ bool m_default_device_changed;
+ LONG m_reference_count;
AUD_LOCAL HRESULT setupRenderClient(IAudioRenderClient*& render_client, UINT32& buffer_size);
@@ -58,6 +60,17 @@ private:
AUD_LOCAL bool setupDevice(DeviceSpecs& specs);
+ // IUnknown implementation
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
+ // IMMNotificationClient implementation
+ HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState);
+ HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId);
+ HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId);
+ HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId);
+ HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key);
+
// delete copy constructor and operator=
WASAPIDevice(const WASAPIDevice&) = delete;
WASAPIDevice& operator=(const WASAPIDevice&) = delete;