aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/wine
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/wine
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/wine')
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp103
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.h20
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeConfig.h162
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.cpp525
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.h145
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDeviceMarshalling.h326
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.cpp151
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.h30
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.c678
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.cpp6
10 files changed, 2146 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp
new file mode 100644
index 00000000..ef3e7ed7
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp
@@ -0,0 +1,103 @@
+
+#include "stdafx.h"
+
+#include "Native.h"
+#include "NativeUtils.h"
+
+#include "../../common/ComponentManager.h"
+
+#if defined(_MSC_VER)
+
+#pragma comment(lib, "advapi32.lib")
+#pragma comment(lib, "bcrypt.lib")
+#pragma comment(lib, "ncrypt.lib")
+#pragma comment(lib, "ole32.lib")
+#pragma comment(lib, "rpcrt4.lib")
+#pragma comment(lib, "shell32.lib")
+#pragma comment(lib, "shlwapi.lib")
+
+#pragma comment(lib, "strmiids.lib")
+
+#if (_WIN32_WINNT >= 0x600)
+#pragma comment(lib, "avrt.lib")
+#endif
+#if defined(MPT_WITH_DIRECTSOUND)
+#pragma comment(lib, "dsound.lib")
+#endif // MPT_WITH_DIRECTSOUND
+#pragma comment(lib, "winmm.lib")
+
+#pragma comment(lib, "ksuser.lib")
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#pragma comment( linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df'\"" )
+#endif
+
+#endif
+
+OPENMPT_NAMESPACE_BEGIN
+
+#if defined(MPT_ASSERT_HANDLER_NEEDED) && defined(MPT_BUILD_WINESUPPORT)
+MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *expr, const char *msg)
+{
+ if(msg)
+ {
+ mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
+ U_("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::Charset::ASCII, msg) + U_(" (") + mpt::ToUnicode(mpt::Charset::ASCII, expr) + U_(")")
+ );
+ } else
+ {
+ mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
+ U_("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::Charset::ASCII, expr)
+ );
+ }
+}
+#endif
+
+namespace Wine
+{
+
+class ComponentManagerSettings
+ : public IComponentManagerSettings
+{
+ virtual bool LoadOnStartup() const { return true; } // required to simplify object lifetimes
+ virtual bool KeepLoaded() const { return true; } // required to simplify object lifetimes
+ virtual bool IsBlocked(const std::string &key) const { MPT_UNREFERENCED_PARAMETER(key); return false; }
+ virtual mpt::PathString Path() const { return mpt::PathString(); }
+};
+
+static ComponentManagerSettings & ComponentManagerSettingsSingleton()
+{
+ static ComponentManagerSettings gs_Settings;
+ return gs_Settings;
+}
+
+void Init()
+{
+ ComponentManager::Init(ComponentManagerSettingsSingleton());
+ ComponentManager::Instance()->Startup();
+}
+
+void Fini()
+{
+ ComponentManager::Release();
+}
+
+} // namespace Wine
+
+OPENMPT_NAMESPACE_END
+
+extern "C" {
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_Init(void)
+{
+ OPENMPT_NAMESPACE::Wine::Init();
+ return 0;
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_Fini(void)
+{
+ OPENMPT_NAMESPACE::Wine::Fini();
+ return 0;
+}
+
+} // extern "C"
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.h b/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.h
new file mode 100644
index 00000000..d08419d2
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.h
@@ -0,0 +1,20 @@
+
+#ifndef OPENMPT_WINE_H
+#define OPENMPT_WINE_H
+
+#include "NativeConfig.h"
+#include "NativeUtils.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_Init(void);
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_Fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // OPENMPT_WINE_H
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeConfig.h b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeConfig.h
new file mode 100644
index 00000000..3652a0da
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeConfig.h
@@ -0,0 +1,162 @@
+
+#ifndef OPENMPT_WNESUPPORT_CONFIG_H
+#define OPENMPT_WNESUPPORT_CONFIG_H
+
+#include <stdint.h>
+
+#if defined(__DOXYGEN__)
+
+#define OPENMPT_API_HELPER_EXPORT
+#define OPENMPT_API_HELPER_IMPORT
+#define OPENMPT_API_HELPER_PUBLIC
+#define OPENMPT_API_HELPER_LOCAL
+
+#elif defined(MPT_WINEGCC)
+
+#define OPENMPT_API_HELPER_EXPORT __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_IMPORT __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden")))
+
+#elif defined(_MSC_VER)
+
+#define OPENMPT_API_HELPER_EXPORT __declspec(dllexport)
+#define OPENMPT_API_HELPER_IMPORT __declspec(dllimport)
+#define OPENMPT_API_HELPER_PUBLIC
+#define OPENMPT_API_HELPER_LOCAL
+
+#elif defined(__GNUC__) || defined(__clang__)
+
+#define OPENMPT_API_HELPER_EXPORT __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_IMPORT __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default")))
+#define OPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden")))
+
+#else
+
+#define OPENMPT_API_HELPER_EXPORT
+#define OPENMPT_API_HELPER_IMPORT
+#define OPENMPT_API_HELPER_PUBLIC
+#define OPENMPT_API_HELPER_LOCAL
+
+#endif
+
+#if defined(__DOXYGEN__)
+
+#define OPENMPT_API_WINE_MS_CDECL
+#define OPENMPT_API_WINE_MS_STDCALL
+#define OPENMPT_API_WINE_MS_FASTCALL
+#define OPENMPT_API_WINE_MS_THISCALL
+#undef OPENMPT_API_WINE_SYSV
+
+#elif defined(MPT_WINEGCC)
+
+#ifdef _WIN64
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi))
+#else
+// winegcc on Ubuntu 16.04, wine-development 1.9.6 completely explodes in
+// incomprehensible ways while parsing __attribute__((cdecl)).
+#if defined(__cdecl)
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi)) __cdecl
+#else
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi)) __attribute__((cdecl))
+#endif
+#if defined(__stdcall)
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi)) __stdcall
+#else
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi)) __attribute__((stdcall))
+#endif
+#if defined(__fastcall)
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi)) __fastcall
+#else
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi)) __attribute__((fastcall))
+#endif
+#if defined(__thiscall)
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi)) __thiscall
+#else
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi)) __attribute__((thiscall))
+#endif
+#endif
+#define OPENMPT_API_WINE_SYSV __attribute__((sysv_abi))
+
+#elif defined(_MSC_VER)
+
+#define OPENMPT_API_WINE_MS_CDECL __cdecl
+#define OPENMPT_API_WINE_MS_STDCALL __stdcall
+#define OPENMPT_API_WINE_MS_FASTCALL __fastcall
+#define OPENMPT_API_WINE_MS_THISCALL __thiscall
+#undef OPENMPT_API_WINE_SYSV
+
+#elif defined(__GNUC__) || defined(__clang__)
+
+#ifdef _WIN64
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi))
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi))
+#else
+// winegcc on Ubuntu 16.04, wine-development 1.9.6 completely explodes in
+// incomprehensible ways while parsing __attribute__((cdecl)).
+#if defined(__cdecl)
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi)) __cdecl
+#else
+#define OPENMPT_API_WINE_MS_CDECL __attribute__((ms_abi)) __attribute__((cdecl))
+#endif
+#if defined(__stdcall)
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi)) __stdcall
+#else
+#define OPENMPT_API_WINE_MS_STDCALL __attribute__((ms_abi)) __attribute__((stdcall))
+#endif
+#if defined(__fastcall)
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi)) __fastcall
+#else
+#define OPENMPT_API_WINE_MS_FASTCALL __attribute__((ms_abi)) __attribute__((fastcall))
+#endif
+#if defined(__thiscall)
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi)) __thiscall
+#else
+#define OPENMPT_API_WINE_MS_THISCALL __attribute__((ms_abi)) __attribute__((thiscall))
+#endif
+#endif
+#define OPENMPT_API_WINE_SYSV __attribute__((sysv_abi))
+
+#endif
+
+#if defined(MODPLUG_TRACKER) && (!(defined(MPT_BUILD_WINESUPPORT) || defined(MPT_BUILD_WINESUPPORT_WRAPPER)))
+
+#define OPENMPT_WINESUPPORT_API
+#define OPENMPT_WINESUPPORT_CALL
+#define OPENMPT_WINESUPPORT_WRAPPER_API
+#define OPENMPT_WINESUPPORT_WRAPPER_CALL
+
+#else
+
+#if defined(__DOXYGEN__)
+#define OPENMPT_WINESUPPORT_CALL OPENMPT_API_WINE_SYSV
+#elif defined(MPT_WINEGCC)
+#define OPENMPT_WINESUPPORT_CALL OPENMPT_API_WINE_SYSV
+#elif defined(_MSC_VER)
+#define OPENMPT_WINESUPPORT_CALL OPENMPT_API_WINE_MS_CDECL
+#elif defined(__GNUC__) || defined(__clang__)
+#define OPENMPT_WINESUPPORT_CALL OPENMPT_API_WINE_SYSV
+#endif
+#define OPENMPT_WINESUPPORT_WRAPPER_CALL OPENMPT_API_WINE_MS_CDECL
+
+#if defined(MPT_BUILD_WINESUPPORT)
+#define OPENMPT_WINESUPPORT_API OPENMPT_API_HELPER_EXPORT
+#else
+#define OPENMPT_WINESUPPORT_API OPENMPT_API_HELPER_IMPORT
+#endif
+
+#if defined(MPT_BUILD_WINESUPPORT_WRAPPER)
+#define OPENMPT_WINESUPPORT_WRAPPER_API OPENMPT_API_HELPER_EXPORT
+#else
+#define OPENMPT_WINESUPPORT_WRAPPER_API OPENMPT_API_HELPER_IMPORT
+#endif
+
+#endif
+
+#endif // OPENMPT_WNESUPPORT_CONFIG_H
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.cpp
new file mode 100644
index 00000000..ed6710a9
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.cpp
@@ -0,0 +1,525 @@
+
+#include "stdafx.h"
+
+#if MPT_COMPILER_MSVC
+#pragma warning(disable:4800) // 'T' : forcing value to bool 'true' or 'false' (performance warning)
+#endif // MPT_COMPILER_MSVC
+
+#include "NativeSoundDevice.h"
+#include "NativeUtils.h"
+
+#include "openmpt/sounddevice/SoundDevice.hpp"
+#include "openmpt/sounddevice/SoundDeviceManager.hpp"
+#include "openmpt/sounddevice/SoundDeviceUtilities.hpp"
+
+#include "../../common/ComponentManager.h"
+
+#include "../../misc/mptOS.h"
+
+#include "NativeSoundDeviceMarshalling.h"
+
+#include <string>
+#include <type_traits>
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+OPENMPT_NAMESPACE_BEGIN
+
+namespace C {
+
+class ComponentSoundDeviceManager
+ : public ComponentBuiltin
+{
+ MPT_DECLARE_COMPONENT_MEMBERS(ComponentSoundDeviceManager, "SoundDeviceManager")
+private:
+ mpt::log::GlobalLogger logger;
+ SoundDevice::Manager manager;
+private:
+ static SoundDevice::SysInfo GetSysInfo()
+ {
+ mpt::OS::Wine::VersionContext wineVersionContext;
+ return SoundDevice::SysInfo(mpt::osinfo::get_class(), mpt::OS::Windows::Version::Current(), mpt::OS::Windows::IsWine(), wineVersionContext.HostClass(), wineVersionContext.Version());
+ }
+
+public:
+ ComponentSoundDeviceManager()
+ : manager(logger, GetSysInfo(), SoundDevice::AppInfo())
+ {
+ return;
+ }
+ virtual ~ComponentSoundDeviceManager() { }
+ bool DoInitialize() override
+ {
+ return true;
+ }
+ SoundDevice::Manager & get() const
+ {
+ return const_cast<SoundDevice::Manager &>(manager);
+ }
+};
+
+static mpt::ustring GetTypePrefix()
+{
+ return U_("Native");
+}
+
+static SoundDevice::Info AddTypePrefix(SoundDevice::Info info)
+{
+ info.type = GetTypePrefix() + U_("-") + info.type;
+ info.apiPath.insert(info.apiPath.begin(), U_("Native"));
+ return info;
+}
+
+static SoundDevice::Info RemoveTypePrefix(SoundDevice::Info info)
+{
+ info.type = info.type.substr(GetTypePrefix().length() + 1);
+ info.apiPath.erase(info.apiPath.begin());
+ return info;
+}
+
+std::string SoundDevice_EnumerateDevices()
+{
+ ComponentHandle<ComponentSoundDeviceManager> manager;
+ if(!IsComponentAvailable(manager))
+ {
+ return std::string();
+ }
+ std::vector<SoundDevice::Info> infos = std::vector<SoundDevice::Info>(manager->get().begin(), manager->get().end());
+ for(auto &info : infos)
+ {
+ info = AddTypePrefix(info);
+ }
+ return json_cast<std::string>(infos);
+}
+
+SoundDevice::IBase * SoundDevice_Construct(std::string info_)
+{
+ MPT_LOG_GLOBAL(LogDebug, "NativeSupport", MPT_UFORMAT("Contruct: {}")(mpt::ToUnicode(mpt::Charset::UTF8, info_)));
+ ComponentHandle<ComponentSoundDeviceManager> manager;
+ if(!IsComponentAvailable(manager))
+ {
+ return nullptr;
+ }
+ SoundDevice::Info info = json_cast<SoundDevice::Info>(info_);
+ info = RemoveTypePrefix(info);
+ return manager->get().CreateSoundDevice(info.GetIdentifier());
+}
+
+class NativeMessageReceiverProxy
+ : public SoundDevice::IMessageReceiver
+{
+private:
+ OpenMPT_SoundDevice_IMessageReceiver impl;
+public:
+ NativeMessageReceiverProxy(const OpenMPT_SoundDevice_IMessageReceiver * impl_)
+ {
+ MemsetZero(impl);
+ if(impl_)
+ {
+ impl = *impl_;
+ }
+ }
+ virtual ~NativeMessageReceiverProxy()
+ {
+ return;
+ }
+public:
+ virtual void SoundDeviceMessage(LogLevel level, const mpt::ustring &str)
+ {
+ if(!impl.SoundDeviceMessageFunc)
+ {
+ return;
+ }
+ return impl.SoundDeviceMessageFunc(impl.inst, level, mpt::ToCharset(mpt::Charset::UTF8, str).c_str());
+ }
+};
+
+class NativeCallbackProxy
+ : public SoundDevice::ICallback
+{
+private:
+ OpenMPT_SoundDevice_ICallback impl;
+public:
+ NativeCallbackProxy(const OpenMPT_SoundDevice_ICallback * impl_)
+ {
+ MemsetZero(impl);
+ if(impl_)
+ {
+ impl = *impl_;
+ }
+ }
+ virtual ~NativeCallbackProxy()
+ {
+ return;
+ }
+public:
+ // main thread
+ virtual uint64 SoundCallbackGetReferenceClockNowNanoseconds() const
+ {
+ if(!impl.SoundCallbackGetReferenceClockNowNanosecondsFunc)
+ {
+ return 0;
+ }
+ uint64_t result = 0;
+ impl.SoundCallbackGetReferenceClockNowNanosecondsFunc(impl.inst, &result);
+ return result;
+ }
+ virtual void SoundCallbackPreStart()
+ {
+ if(!impl.SoundCallbackPreStartFunc)
+ {
+ return;
+ }
+ return impl.SoundCallbackPreStartFunc(impl.inst);
+ }
+ virtual void SoundCallbackPostStop()
+ {
+ if(!impl.SoundCallbackPostStopFunc)
+ {
+ return;
+ }
+ return impl.SoundCallbackPostStopFunc(impl.inst);
+ }
+ virtual bool SoundCallbackIsLockedByCurrentThread() const
+ {
+ if(!impl.SoundCallbackIsLockedByCurrentThreadFunc)
+ {
+ return 0;
+ }
+ uintptr_t result = 0;
+ impl.SoundCallbackIsLockedByCurrentThreadFunc(impl.inst, &result);
+ return result;
+ }
+ // audio thread
+ virtual void SoundCallbackLock()
+ {
+ if(!impl.SoundCallbackLockFunc)
+ {
+ return;
+ }
+ return impl.SoundCallbackLockFunc(impl.inst);
+ }
+ virtual uint64 SoundCallbackLockedGetReferenceClockNowNanoseconds() const
+ {
+ if(!impl.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc)
+ {
+ return 0;
+ }
+ uint64_t result = 0;
+ impl.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc(impl.inst, &result);
+ return result;
+ }
+ virtual void SoundCallbackLockedProcessPrepare(SoundDevice::TimeInfo timeInfo)
+ {
+ if(!impl.SoundCallbackLockedProcessPrepareFunc)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_TimeInfo c_timeInfo = C::encode(timeInfo);
+ return impl.SoundCallbackLockedProcessPrepareFunc(impl.inst, &c_timeInfo);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, uint8 *buffer, const uint8 *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessUint8Func)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessUint8Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int8 *buffer, const int8 *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessInt8Func)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessInt8Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int16 *buffer, const int16 *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessInt16Func)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessInt16Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int24 *buffer, const int24 *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessInt24Func)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessInt24Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int32 *buffer, const int32 *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessInt32Func)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessInt32Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, float *buffer, const float *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessFloatFunc)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessFloatFunc(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, double *buffer, const double *inputBuffer)
+ {
+ if(!impl.SoundCallbackLockedProcessDoubleFunc)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
+ return impl.SoundCallbackLockedProcessDoubleFunc(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
+ }
+ virtual void SoundCallbackLockedProcessDone(SoundDevice::TimeInfo timeInfo)
+ {
+ if(!impl.SoundCallbackLockedProcessDoneFunc)
+ {
+ return;
+ }
+ OpenMPT_SoundDevice_TimeInfo c_timeInfo = C::encode(timeInfo);
+ return impl.SoundCallbackLockedProcessDoneFunc(impl.inst, &c_timeInfo);
+ }
+ virtual void SoundCallbackUnlock()
+ {
+ if(!impl.SoundCallbackUnlockFunc)
+ {
+ return;
+ }
+ return impl.SoundCallbackUnlockFunc(impl.inst);
+ }
+};
+
+} // namespace C
+
+OPENMPT_NAMESPACE_END
+
+extern "C" {
+
+struct OpenMPT_SoundDevice {
+ OPENMPT_NAMESPACE::SoundDevice::IBase * impl;
+ OPENMPT_NAMESPACE::C::NativeMessageReceiverProxy * messageReceiver;
+ OPENMPT_NAMESPACE::C::NativeCallbackProxy * callback;
+};
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EnumerateDevices() {
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::C::SoundDevice_EnumerateDevices().c_str() );
+}
+
+OPENMPT_WINESUPPORT_API OpenMPT_SoundDevice * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Construct( const char * info ) {
+ if ( !info ) {
+ return nullptr;
+ }
+ OpenMPT_SoundDevice * result = reinterpret_cast< OpenMPT_SoundDevice * >( OpenMPT_Alloc( sizeof( OpenMPT_SoundDevice ) ) );
+ if ( !result ) {
+ return nullptr;
+ }
+ result->impl = OPENMPT_NAMESPACE::C::SoundDevice_Construct( info );
+ if ( !result->impl ) {
+ OpenMPT_Free( result );
+ return nullptr;
+ }
+ return result;
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Destruct( OpenMPT_SoundDevice * sd ) {
+ if ( sd ) {
+ if ( sd->impl ) {
+ sd->impl->SetMessageReceiver( nullptr );
+ delete sd->messageReceiver;
+ sd->messageReceiver = nullptr;
+ delete sd->impl;
+ sd->impl = nullptr;
+ }
+ OpenMPT_Free( sd );
+ }
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetMessageReceiver( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_IMessageReceiver * receiver ) {
+ if ( !sd ) {
+ return;
+ }
+ if ( !sd->impl ) {
+ return;
+ }
+ sd->impl->SetMessageReceiver( nullptr );
+ delete sd->messageReceiver;
+ sd->messageReceiver = nullptr;
+ sd->messageReceiver = new OPENMPT_NAMESPACE::C::NativeMessageReceiverProxy( receiver );
+ sd->impl->SetMessageReceiver( sd->messageReceiver );
+ return;
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetCallback( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_ICallback * callback ) {
+ if ( !sd ) {
+ return;
+ }
+ if ( !sd->impl ) {
+ return;
+ }
+ sd->impl->SetCallback( nullptr );
+ delete sd->callback;
+ sd->callback = nullptr;
+ sd->callback = new OPENMPT_NAMESPACE::C::NativeCallbackProxy( callback );
+ sd->impl->SetCallback( sd->callback );
+ return;
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceInfo( const OpenMPT_SoundDevice * sd ) {
+ OPENMPT_NAMESPACE::SoundDevice::Info info = sd->impl->GetDeviceInfo();
+ info = OPENMPT_NAMESPACE::C::AddTypePrefix(info);
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetDeviceInfo() ).c_str() );
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceCaps( const OpenMPT_SoundDevice * sd ) {
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetDeviceCaps() ).c_str() );
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceDynamicCaps( OpenMPT_SoundDevice * sd, const char * baseSampleRates ) {
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetDeviceDynamicCaps( OPENMPT_NAMESPACE::json_cast<std::vector<OPENMPT_NAMESPACE::uint32> >( std::string(baseSampleRates) ) ) ).c_str() );
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Init( OpenMPT_SoundDevice * sd, const char * appInfo ) {
+ return sd->impl->Init( OPENMPT_NAMESPACE::json_cast<OPENMPT_NAMESPACE::SoundDevice::AppInfo>( std::string(appInfo) ) );
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Open( OpenMPT_SoundDevice * sd, const char * settings ) {
+ return sd->impl->Open( OPENMPT_NAMESPACE::json_cast<OPENMPT_NAMESPACE::SoundDevice::Settings>( std::string(settings) ) );
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Close( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->Close();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Start( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->Start();
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Stop( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->Stop();
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetRequestFlags( const OpenMPT_SoundDevice * sd, uint32_t * result) {
+ *result = sd->impl->GetRequestFlags().GetRaw();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsInited( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->IsInited();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsOpen( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->IsOpen();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsAvailable( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->IsAvailable();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlaying( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->IsPlaying();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlayingSilence( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->IsPlayingSilence();
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_StopAndAvoidPlayingSilence( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->StopAndAvoidPlayingSilence();
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EndPlayingSilence( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->EndPlayingSilence();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OnIdle( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->OnIdle();
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetSettings( const OpenMPT_SoundDevice * sd ) {
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetSettings() ).c_str() );
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetActualSampleFormat( const OpenMPT_SoundDevice * sd, int32_t * result ) {
+ *result = OPENMPT_NAMESPACE::mpt::to_underlying<OPENMPT_NAMESPACE::SampleFormat::Enum>(sd->impl->GetActualSampleFormat());
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetEffectiveBufferAttributes( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_BufferAttributes * result ) {
+ *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetEffectiveBufferAttributes() );
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetTimeInfo( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_TimeInfo * result ) {
+ *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetTimeInfo() );
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStreamPosition( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_StreamPosition * result ) {
+ *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetStreamPosition() );
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugIsFragileDevice( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->DebugIsFragileDevice();
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugInRealtimeCallback( const OpenMPT_SoundDevice * sd ) {
+ return sd->impl->DebugInRealtimeCallback();
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStatistics( const OpenMPT_SoundDevice * sd ) {
+ return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetStatistics() ).c_str() );
+}
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OpenDriverSettings( OpenMPT_SoundDevice * sd ) {
+ return sd->impl->OpenDriverSettings();
+}
+
+typedef struct OpenMPT_PriorityBooster {
+#ifndef _MSC_VER
+ OPENMPT_NAMESPACE::SoundDevice::ThreadPriorityGuard * impl;
+#else
+ void * dummy;
+#endif
+} OpenMPT_PriorityBooster;
+
+OPENMPT_WINESUPPORT_API OpenMPT_PriorityBooster * OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Construct_From_SoundDevice( const OpenMPT_SoundDevice * sd ) {
+#if !MPT_OS_WINDOWS
+ OpenMPT_PriorityBooster * pb = (OpenMPT_PriorityBooster*)OpenMPT_Alloc( sizeof( OpenMPT_PriorityBooster ) );
+ pb->impl = new OPENMPT_NAMESPACE::SoundDevice::ThreadPriorityGuard
+ ( dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetLogger()
+ , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetSettings().BoostThreadPriority
+ , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadRealtimePosix
+ , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadNicenessPosix
+ , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadRtprioPosix
+ );
+ return pb;
+#else
+ MPT_UNREFERENCED_PARAMETER(sd);
+ return nullptr;
+#endif
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Destruct( OpenMPT_PriorityBooster * pb ) {
+#if !MPT_OS_WINDOWS
+ delete pb->impl;
+ pb->impl = nullptr;
+ OpenMPT_Free( pb );
+#else
+ MPT_UNREFERENCED_PARAMETER(pb);
+#endif
+}
+
+} // extern "C"
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.h b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.h
new file mode 100644
index 00000000..932fcd69
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDevice.h
@@ -0,0 +1,145 @@
+
+#ifndef OPENMPT_WINE_SOUNDDEVICE_H
+#define OPENMPT_WINE_SOUNDDEVICE_H
+
+#include "NativeConfig.h"
+#include "NativeUtils.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EnumerateDevices();
+
+typedef void OpenMPT_int24;
+
+typedef struct OpenMPT_SoundDevice_StreamPosition {
+ int64_t Frames;
+ double Seconds;
+} OpenMPT_SoundDevice_StreamPosition;
+
+typedef struct OpenMPT_SoundDevice_TimeInfo {
+ int64_t SyncPointStreamFrames;
+ uint64_t SyncPointSystemTimestamp;
+ double Speed;
+ OpenMPT_SoundDevice_StreamPosition RenderStreamPositionBefore;
+ OpenMPT_SoundDevice_StreamPosition RenderStreamPositionAfter;
+ double Latency;
+} OpenMPT_SoundDevice_TimeInfo;
+
+typedef struct OpenMPT_SoundDevice_Flags {
+ uint8_t WantsClippedOutput;
+ uint8_t pad1;
+ uint16_t pad2;
+ uint32_t pad3;
+} OpenMPT_SoundDevice_Flags;
+
+typedef struct OpenMPT_SoundDevice_BufferFormat {
+ uint32_t Samplerate;
+ uint32_t Channels;
+ uint8_t InputChannels;
+ uint8_t pad1;
+ uint16_t pad2;
+ int32_t sampleFormat;
+ uint8_t WantsClippedOutput;
+ uint8_t pad3;
+ uint16_t pad4;
+ int32_t DitherType;
+} OpenMPT_SoundDevice_BufferFormat;
+
+typedef struct OpenMPT_SoundDevice_BufferAttributes {
+ double Latency;
+ double UpdateInterval;
+ int32_t NumBuffers;
+ uint32_t pad1;
+} OpenMPT_SoundDevice_BufferAttributes;
+
+typedef struct OpenMPT_SoundDevice_RequestFlags {
+ uint32_t RequestFlags;
+ uint32_t pad1;
+} OpenMPT_SoundDevice_RequestFlags;
+
+typedef struct OpenMPT_SoundDevice OpenMPT_SoundDevice;
+
+typedef struct OpenMPT_SoundDevice_IMessageReceiver {
+ void * inst;
+ void (OPENMPT_WINESUPPORT_CALL * SoundDeviceMessageFunc)( void * inst, uintptr_t level, const char * message );
+} OpenMPT_SoundDevice_IMessageReceiver;
+
+typedef struct OpenMPT_SoundDevice_ICallback {
+ void * inst;
+ // main thread
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackGetReferenceClockNowNanosecondsFunc)( void * inst, uint64_t * result );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackPreStartFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackPostStopFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackIsLockedByCurrentThreadFunc)( void * inst, uintptr_t * result );
+ // audio thread
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedGetReferenceClockNowNanosecondsFunc)( void * inst, uint64_t * result );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessPrepareFunc)( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessUint8Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, uint8_t * buffer, const uint8_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessInt8Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int8_t * buffer, const int8_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessInt16Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int16_t * buffer, const int16_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessInt24Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, OpenMPT_int24 * buffer, const OpenMPT_int24 * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessInt32Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int32_t * buffer, const int32_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessFloatFunc)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, float * buffer, const float * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessDoubleFunc)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, double * buffer, const double * inputBuffer );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackLockedProcessDoneFunc)( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo );
+ void (OPENMPT_WINESUPPORT_CALL * SoundCallbackUnlockFunc)( void * inst );
+} OpenMPT_SoundDevice_ICallback;
+
+OPENMPT_WINESUPPORT_API OpenMPT_SoundDevice * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Construct( const char * info );
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Destruct( OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetMessageReceiver( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_IMessageReceiver * receiver );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetCallback( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_ICallback * callback );
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceInfo( const OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceCaps( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceDynamicCaps( OpenMPT_SoundDevice * sd, const char * baseSampleRates );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Init( OpenMPT_SoundDevice * sd, const char * appInfo );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Open( OpenMPT_SoundDevice * sd, const char * settings );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Close( OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Start( OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Stop( OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetRequestFlags( const OpenMPT_SoundDevice * sd, uint32_t * result );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsInited( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsOpen( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsAvailable( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlaying( const OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlayingSilence( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_StopAndAvoidPlayingSilence( OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EndPlayingSilence( OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OnIdle( OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetSettings( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetActualSampleFormat( const OpenMPT_SoundDevice * sd, int32_t * result );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetEffectiveBufferAttributes( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_BufferAttributes * result );
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetTimeInfo( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_TimeInfo * result );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStreamPosition( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_StreamPosition * result );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugIsFragileDevice( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugInRealtimeCallback( const OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStatistics( const OpenMPT_SoundDevice * sd );
+
+OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OpenDriverSettings( OpenMPT_SoundDevice * sd );
+
+typedef struct OpenMPT_PriorityBooster OpenMPT_PriorityBooster;
+OPENMPT_WINESUPPORT_API OpenMPT_PriorityBooster * OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Construct_From_SoundDevice( const OpenMPT_SoundDevice * sd );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Destruct( OpenMPT_PriorityBooster * pb );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // OPENMPT_WINE_SOUNDDEVICE_H
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDeviceMarshalling.h b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDeviceMarshalling.h
new file mode 100644
index 00000000..95b2ae99
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeSoundDeviceMarshalling.h
@@ -0,0 +1,326 @@
+
+#pragma once
+
+#include "openmpt/all/BuildSettings.hpp"
+
+#include "NativeSoundDevice.h"
+
+#include "openmpt/sounddevice/SoundDevice.hpp"
+
+#ifdef MPT_WITH_NLOHMANNJSON
+
+// https://github.com/nlohmann/json/issues/1204
+#if MPT_COMPILER_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127) // conditional expression is constant
+#endif // MPT_COMPILER_MSVC
+#include "mpt/json/json.hpp"
+#if MPT_COMPILER_MSVC
+#pragma warning(pop)
+#endif // MPT_COMPILER_MSVC
+
+#endif // MPT_WITH_NLOHMANNJSON
+
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+
+#ifdef MPT_WITH_NLOHMANNJSON
+
+inline void to_json(nlohmann::json &j, const SampleFormat &val)
+{
+ j = SampleFormat::ToInt(val);
+}
+inline void from_json(const nlohmann::json &j, SampleFormat &val)
+{
+ val = SampleFormat::FromInt(j);
+}
+
+namespace SoundDevice
+{
+
+ inline void to_json(nlohmann::json &j, const SoundDevice::ChannelMapping &val)
+ {
+ j = val.ToUString();
+ }
+ inline void from_json(const nlohmann::json &j, SoundDevice::ChannelMapping &val)
+ {
+ val = SoundDevice::ChannelMapping::FromString(j);
+ }
+
+ inline void to_json(nlohmann::json &j, const SoundDevice::Info::Default &val)
+ {
+ j = static_cast<int>(val);
+ }
+ inline void from_json(const nlohmann::json &j, SoundDevice::Info::Default &val)
+ {
+ val = static_cast<SoundDevice::Info::Default>(static_cast<int>(j));
+ }
+} // namespace SoundDevice
+
+
+
+namespace SoundDevice
+{
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::ManagerFlags
+ ,defaultFor
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::Flags
+ ,usability
+ ,level
+ ,compatible
+ ,api
+ ,io
+ ,mixing
+ ,implementor
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info
+ ,type
+ ,internalID
+ ,name
+ ,apiName
+ ,apiPath
+ ,default_
+ ,useNameAsIdentifier
+ ,managerFlags
+ ,flags
+ ,extraData
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::AppInfo
+ ,Name
+ ,BoostedThreadPriorityXP
+ ,BoostedThreadMMCSSClassVista
+ ,BoostedThreadRealtimePosix
+ ,BoostedThreadNicenessPosix
+ ,BoostedThreadRtprioPosix
+ ,MaskDriverCrashes
+ ,AllowDeferredProcessing
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Settings
+ ,Latency
+ ,UpdateInterval
+ ,Samplerate
+ ,Channels
+ ,InputChannels
+ ,sampleFormat
+ ,ExclusiveMode
+ ,BoostThreadPriority
+ ,KeepDeviceRunning
+ ,UseHardwareTiming
+ ,DitherType
+ ,InputSourceID
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Caps
+ ,Available
+ ,CanUpdateInterval
+ ,CanSampleFormat
+ ,CanExclusiveMode
+ ,CanBoostThreadPriority
+ ,CanKeepDeviceRunning
+ ,CanUseHardwareTiming
+ ,CanChannelMapping
+ ,CanInput
+ ,HasNamedInputSources
+ ,CanDriverPanel
+ ,HasInternalDither
+ ,ExclusiveModeDescription
+ ,LatencyMin
+ ,LatencyMax
+ ,UpdateIntervalMin
+ ,UpdateIntervalMax
+ ,DefaultSettings
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::DynamicCaps
+ ,currentSampleRate
+ ,supportedSampleRates
+ ,supportedExclusiveSampleRates
+ ,supportedSampleFormats
+ ,supportedExclusiveModeSampleFormats
+ ,channelNames
+ ,inputSourceNames
+ )
+
+ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Statistics
+ ,InstantaneousLatency
+ ,LastUpdateInterval
+ ,text
+ )
+
+} // namespace SoundDevice
+
+
+
+template <typename Tdst, typename Tsrc>
+struct json_cast_impl
+{
+ Tdst operator () (const Tsrc &src);
+};
+
+
+template <typename Tdst, typename Tsrc>
+Tdst json_cast(const Tsrc &src)
+{
+ return json_cast_impl<Tdst, Tsrc>()(src);
+}
+
+
+template <typename Tsrc>
+struct json_cast_impl<nlohmann::json, Tsrc>
+{
+ nlohmann::json operator () (const Tsrc &src)
+ {
+ return static_cast<nlohmann::json>(src);
+ }
+};
+
+template <typename Tdst>
+struct json_cast_impl<Tdst, nlohmann::json>
+{
+ Tdst operator () (const nlohmann::json &src)
+ {
+ return src.get<Tdst>();
+ }
+};
+
+template <typename Tsrc>
+struct json_cast_impl<std::string, Tsrc>
+{
+ std::string operator () (const Tsrc &src)
+ {
+ return json_cast<nlohmann::json>(src).dump(4);
+ }
+};
+
+template <typename Tdst>
+struct json_cast_impl<Tdst, std::string>
+{
+ Tdst operator () (const std::string &str)
+ {
+ return json_cast<Tdst>(nlohmann::json::parse(str));
+ }
+};
+
+#endif // MPT_WITH_NLOHMANNJSON
+
+
+
+namespace C {
+
+static_assert(sizeof(OpenMPT_SoundDevice_StreamPosition) % 8 == 0);
+inline OpenMPT_SoundDevice_StreamPosition encode(SoundDevice::StreamPosition src) {
+ OpenMPT_SoundDevice_StreamPosition dst;
+ MemsetZero(dst);
+ dst.Frames = src.Frames;
+ dst.Seconds = src.Seconds;
+ return dst;
+}
+inline SoundDevice::StreamPosition decode(OpenMPT_SoundDevice_StreamPosition src) {
+ SoundDevice::StreamPosition dst;
+ dst.Frames = src.Frames;
+ dst.Seconds = src.Seconds;
+ return dst;
+}
+
+static_assert(sizeof(OpenMPT_SoundDevice_TimeInfo) % 8 == 0);
+inline OpenMPT_SoundDevice_TimeInfo encode(SoundDevice::TimeInfo src) {
+ OpenMPT_SoundDevice_TimeInfo dst;
+ MemsetZero(dst);
+ dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
+ dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
+ dst.Speed = src.Speed;
+ dst.RenderStreamPositionBefore = encode(src.RenderStreamPositionBefore);
+ dst.RenderStreamPositionAfter = encode(src.RenderStreamPositionAfter);
+ dst.Latency = src.Latency;
+ return dst;
+}
+inline SoundDevice::TimeInfo decode(OpenMPT_SoundDevice_TimeInfo src) {
+ SoundDevice::TimeInfo dst;
+ dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
+ dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
+ dst.Speed = src.Speed;
+ dst.RenderStreamPositionBefore = decode(src.RenderStreamPositionBefore);
+ dst.RenderStreamPositionAfter = decode(src.RenderStreamPositionAfter);
+ dst.Latency = src.Latency;
+ return dst;
+}
+
+static_assert(sizeof(OpenMPT_SoundDevice_Flags) % 8 == 0);
+inline OpenMPT_SoundDevice_Flags encode(SoundDevice::Flags src) {
+ OpenMPT_SoundDevice_Flags dst;
+ MemsetZero(dst);
+ dst.WantsClippedOutput = src.WantsClippedOutput;
+ return dst;
+}
+inline SoundDevice::Flags decode(OpenMPT_SoundDevice_Flags src) {
+ SoundDevice::Flags dst;
+ dst.WantsClippedOutput = src.WantsClippedOutput;
+ return dst;
+}
+
+static_assert(sizeof(OpenMPT_SoundDevice_BufferFormat) % 8 == 0);
+inline OpenMPT_SoundDevice_BufferFormat encode(SoundDevice::BufferFormat src) {
+ OpenMPT_SoundDevice_BufferFormat dst;
+ MemsetZero(dst);
+ dst.Samplerate = src.Samplerate;
+ dst.Channels = src.Channels;
+ dst.InputChannels = src.InputChannels;
+ dst.sampleFormat = SampleFormat::ToInt(src.sampleFormat);
+ dst.WantsClippedOutput = src.WantsClippedOutput;
+ dst.DitherType = src.DitherType;
+ return dst;
+}
+inline SoundDevice::BufferFormat decode(OpenMPT_SoundDevice_BufferFormat src) {
+ SoundDevice::BufferFormat dst;
+ dst.Samplerate = src.Samplerate;
+ dst.Channels = src.Channels;
+ dst.InputChannels = src.InputChannels;
+ dst.sampleFormat = SampleFormat::FromInt(src.sampleFormat);
+ dst.WantsClippedOutput = src.WantsClippedOutput;
+ dst.DitherType = src.DitherType;
+ return dst;
+}
+
+static_assert(sizeof(OpenMPT_SoundDevice_BufferAttributes) % 8 == 0);
+inline OpenMPT_SoundDevice_BufferAttributes encode(SoundDevice::BufferAttributes src) {
+ OpenMPT_SoundDevice_BufferAttributes dst;
+ MemsetZero(dst);
+ dst.Latency = src.Latency;
+ dst.UpdateInterval = src.UpdateInterval;
+ dst.NumBuffers = src.NumBuffers;
+ return dst;
+}
+inline SoundDevice::BufferAttributes decode(OpenMPT_SoundDevice_BufferAttributes src) {
+ SoundDevice::BufferAttributes dst;
+ dst.Latency = src.Latency;
+ dst.UpdateInterval = src.UpdateInterval;
+ dst.NumBuffers = src.NumBuffers;
+ return dst;
+}
+
+static_assert(sizeof(OpenMPT_SoundDevice_RequestFlags) % 8 == 0);
+inline OpenMPT_SoundDevice_RequestFlags encode(FlagSet<SoundDevice::RequestFlags> src) {
+ OpenMPT_SoundDevice_RequestFlags dst;
+ MemsetZero(dst);
+ dst.RequestFlags = src.GetRaw();
+ return dst;
+}
+inline FlagSet<SoundDevice::RequestFlags> decode(OpenMPT_SoundDevice_RequestFlags src) {
+ FlagSet<SoundDevice::RequestFlags> dst;
+ dst.SetRaw(src.RequestFlags);
+ return dst;
+}
+
+} // namespace C
+
+
+
+OPENMPT_NAMESPACE_END
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.cpp
new file mode 100644
index 00000000..d4a5805e
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.cpp
@@ -0,0 +1,151 @@
+
+#include "stdafx.h"
+
+#include "NativeUtils.h"
+
+#include <string>
+#ifndef _MSC_VER
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#endif
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+OPENMPT_NAMESPACE_BEGIN
+
+#ifndef _MSC_VER
+
+namespace mpt {
+
+class semaphore {
+private:
+ unsigned int count;
+ unsigned int waiters_count;
+ std::mutex mutex;
+ std::condition_variable count_nonzero;
+public:
+ semaphore( unsigned int initial_count = 0 )
+ : count(initial_count)
+ , waiters_count(0)
+ {
+ return;
+ }
+ ~semaphore() {
+ return;
+ }
+ void wait() {
+ std::unique_lock<std::mutex> l(mutex);
+ waiters_count++;
+ while ( count == 0 ) {
+ count_nonzero.wait( l );
+ }
+ waiters_count--;
+ count--;
+ }
+ void post() {
+ std::unique_lock<std::mutex> l(mutex);
+ if ( waiters_count > 0 ) {
+ count_nonzero.notify_one();
+ }
+ count++;
+ }
+ void lock() {
+ wait();
+ }
+ void unlock() {
+ post();
+ }
+};
+
+} // namespace mpt
+
+#endif
+
+OPENMPT_NAMESPACE_END
+
+extern "C" {
+
+OPENMPT_WINESUPPORT_API void * OPENMPT_WINESUPPORT_CALL OpenMPT_Alloc( size_t size ) {
+ return calloc( 1, size );
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Free( void * mem ) {
+ if ( mem == nullptr ) {
+ return;
+ }
+ free( mem );
+ return;
+}
+
+OPENMPT_WINESUPPORT_API size_t OPENMPT_WINESUPPORT_CALL OpenMPT_String_Length( const char * str ) {
+ size_t len = 0;
+ if ( !str ) {
+ return len;
+ }
+ len = strlen( str );
+ return len;
+}
+
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_String_Duplicate( const char * src ) {
+ if ( !src ) {
+ return strdup( "" );
+ }
+ return strdup( src );
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_String_Free( char * str ) {
+ OpenMPT_Free( str );
+}
+
+typedef struct OpenMPT_Semaphore {
+#ifndef _MSC_VER
+ OPENMPT_NAMESPACE::mpt::semaphore * impl;
+#else
+ void * dummy;
+#endif
+} OpenMPT_Semaphore;
+
+OPENMPT_WINESUPPORT_API OpenMPT_Semaphore * OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Construct(void) {
+#ifndef _MSC_VER
+ OpenMPT_Semaphore * sem = (OpenMPT_Semaphore*)OpenMPT_Alloc( sizeof( OpenMPT_Semaphore ) );
+ sem->impl = new OPENMPT_NAMESPACE::mpt::semaphore(0);
+ return sem;
+#else
+ return nullptr;
+#endif
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Destruct( OpenMPT_Semaphore * sem ) {
+#ifndef _MSC_VER
+ delete sem->impl;
+ sem->impl = nullptr;
+ OpenMPT_Free( sem );
+#else
+ MPT_UNREFERENCED_PARAMETER(sem);
+#endif
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Wait( OpenMPT_Semaphore * sem ) {
+#ifndef _MSC_VER
+ sem->impl->wait();
+#else
+ MPT_UNREFERENCED_PARAMETER(sem);
+#endif
+}
+
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Post( OpenMPT_Semaphore * sem ) {
+#ifndef _MSC_VER
+ sem->impl->post();
+#else
+ MPT_UNREFERENCED_PARAMETER(sem);
+#endif
+}
+
+} // extern "C"
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.h b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.h
new file mode 100644
index 00000000..0af4f272
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/NativeUtils.h
@@ -0,0 +1,30 @@
+
+#ifndef OPENMPT_WINE_UTILS_H
+#define OPENMPT_WINE_UTILS_H
+
+#include "NativeConfig.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OPENMPT_WINESUPPORT_API void * OPENMPT_WINESUPPORT_CALL OpenMPT_Alloc( size_t size );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Free( void * mem );
+
+OPENMPT_WINESUPPORT_API size_t OPENMPT_WINESUPPORT_CALL OpenMPT_String_Length( const char * str );
+OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_String_Duplicate( const char * src );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_String_Free( char * str );
+
+typedef struct OpenMPT_Semaphore OpenMPT_Semaphore;
+OPENMPT_WINESUPPORT_API OpenMPT_Semaphore * OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Construct(void);
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Destruct( OpenMPT_Semaphore * sem );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Wait( OpenMPT_Semaphore * sem );
+OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Post( OpenMPT_Semaphore * sem );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // OPENMPT_WINE_UTILS_H
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.c b/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.c
new file mode 100644
index 00000000..019f408e
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.c
@@ -0,0 +1,678 @@
+
+#if defined(MPT_BUILD_WINESUPPORT_WRAPPER)
+
+#include "NativeConfig.h"
+
+#include <windows.h>
+
+#include <stdint.h>
+
+#include "Native.h"
+#include "NativeUtils.h"
+#include "NativeSoundDevice.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4098) /* 'void' function returning a value */
+#endif
+
+#define WINE_THREAD
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_Init(void) {
+ return OpenMPT_Init();
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_Fini(void) {
+ return OpenMPT_Fini();
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_Alloc( size_t size ) {
+ return OpenMPT_Alloc( size );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_Free( void * mem ) {
+ return OpenMPT_Free( mem );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API size_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_String_Length( const char * str ) {
+ return OpenMPT_String_Length( str );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_String_Duplicate( const char * src ) {
+ return OpenMPT_String_Duplicate( src );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_String_Free( char * str ) {
+ return OpenMPT_String_Free( str );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_EnumerateDevices() {
+ return OpenMPT_SoundDevice_EnumerateDevices();
+}
+
+typedef struct OpenMPT_Wine_Wrapper_SoundDevice_IMessageReceiver {
+ void * inst;
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundDeviceMessageFunc)( void * inst, uintptr_t level, const char * message );
+} OpenMPT_Wine_Wrapper_SoundDevice_IMessageReceiver;
+
+typedef struct OpenMPT_Wine_Wrapper_SoundDevice_ICallback {
+ void * inst;
+ // main thread
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackGetReferenceClockNowNanosecondsFunc)( void * inst, uint64_t * result );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackPreStartFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackPostStopFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackIsLockedByCurrentThreadFunc)( void * inst, uintptr_t * result );
+ // audio thread
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockFunc)( void * inst );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedGetReferenceClockNowNanosecondsFunc)( void * inst, uint64_t * result );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessPrepareFunc)( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessUint8Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, uint8_t * buffer, const uint8_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessInt8Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int8_t * buffer, const int8_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessInt16Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int16_t * buffer, const int16_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessInt24Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, OpenMPT_int24 * buffer, const OpenMPT_int24 * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessInt32Func)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int32_t * buffer, const int32_t * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessFloatFunc)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, float * buffer, const float * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessDoubleFunc)( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, double * buffer, const double * inputBuffer );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackLockedProcessDoneFunc)( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo );
+ void (OPENMPT_WINESUPPORT_WRAPPER_CALL * SoundCallbackUnlockFunc)( void * inst );
+} OpenMPT_Wine_Wrapper_SoundDevice_ICallback;
+
+#ifdef WINE_THREAD
+typedef enum OpenMPT_Wine_Wrapper_AudioThreadCommand {
+ AudioThreadCommandInvalid = -1
+ , AudioThreadCommandExit = 0
+ , AudioThreadCommandLock = 1
+ , AudioThreadCommandClock = 2
+ , AudioThreadCommandReadPrepare = 3
+ , AudioThreadCommandReadUint8 = 4
+ , AudioThreadCommandReadInt8 = 5
+ , AudioThreadCommandReadInt16 = 6
+ , AudioThreadCommandReadInt24 = 7
+ , AudioThreadCommandReadInt32 = 8
+ , AudioThreadCommandReadFloat = 9
+ , AudioThreadCommandReadDouble = 10
+ , AudioThreadCommandReadDone = 11
+ , AudioThreadCommandUnlock = 12
+} OpenMPT_Wine_Wrapper_AudioThreadCommand;
+#endif
+
+typedef struct OpenMPT_Wine_Wrapper_SoundDevice {
+ OpenMPT_SoundDevice * impl;
+ OpenMPT_SoundDevice_IMessageReceiver native_receiver;
+ OpenMPT_SoundDevice_ICallback native_callback;
+ OpenMPT_Wine_Wrapper_SoundDevice_IMessageReceiver wine_receiver;
+ OpenMPT_Wine_Wrapper_SoundDevice_ICallback wine_callback;
+#ifdef WINE_THREAD
+ HANDLE audiothread_startup_done;
+ OpenMPT_Semaphore * audiothread_sem_request;
+ OpenMPT_Semaphore * audiothread_sem_done;
+ OpenMPT_Wine_Wrapper_AudioThreadCommand audiothread_command;
+ const OpenMPT_SoundDevice_TimeInfo * audiothread_command_timeInfo;
+ const OpenMPT_SoundDevice_BufferFormat * audiothread_command_bufferFormat;
+ const OpenMPT_SoundDevice_BufferAttributes * audiothread_command_bufferAttributes;
+ uintptr_t audiothread_command_numFrames;
+ union {
+ uint8_t * buf_uint8;
+ int8_t * buf_int8;
+ int16_t * buf_int16;
+ OpenMPT_int24 * buf_int24;
+ int32_t * buf_int32;
+ float * buf_float;
+ double * buf_double;
+ } audiothread_command_buffer;
+ union {
+ const uint8_t * buf_uint8;
+ const int8_t * buf_int8;
+ const int16_t * buf_int16;
+ const OpenMPT_int24 * buf_int24;
+ const int32_t * buf_int32;
+ const float * buf_float;
+ const double * buf_double;
+ } audiothread_command_inputBuffer;
+ uint64_t * audiothread_command_result;
+ HANDLE audiothread;
+ OpenMPT_PriorityBooster * priority_booster;
+#endif
+} OpenMPT_Wine_Wrapper_SoundDevice;
+
+static void OPENMPT_WINESUPPORT_CALL SoundDeviceMessageFunc( void * inst, uintptr_t level, const char * message ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+ return sd->wine_receiver.SoundDeviceMessageFunc( sd->wine_receiver.inst, level, message );
+}
+
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackGetReferenceClockNowNanosecondsFunc( void * inst, uint64_t * result ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+ return sd->wine_callback.SoundCallbackGetReferenceClockNowNanosecondsFunc( sd->wine_callback.inst, result );
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackPreStartFunc( void * inst ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+ return sd->wine_callback.SoundCallbackPreStartFunc( sd->wine_callback.inst );
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackPostStopFunc( void * inst ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+ return sd->wine_callback.SoundCallbackPostStopFunc( sd->wine_callback.inst );
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackIsLockedByCurrentThreadFunc( void * inst, uintptr_t * result ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+ return sd->wine_callback.SoundCallbackIsLockedByCurrentThreadFunc( sd->wine_callback.inst, result );
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockFunc( void * inst ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandLock;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockFunc( sd->wine_callback.inst );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedGetReferenceClockNowNanosecondsFunc( void * inst, uint64_t * result ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandClock;
+ sd->audiothread_command_result = result;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc( sd->wine_callback.inst, result );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessPrepareFunc( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadPrepare;
+ sd->audiothread_command_timeInfo = timeInfo;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessPrepareFunc( sd->wine_callback.inst, timeInfo );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessUint8Func( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, uint8_t * buffer, const uint8_t * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadUint8;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_uint8 = buffer;
+ sd->audiothread_command_inputBuffer.buf_uint8 = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessUint8Func( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessInt8Func( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int8_t * buffer, const int8_t * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadInt8;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_int8 = buffer;
+ sd->audiothread_command_inputBuffer.buf_int8 = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessInt8Func( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessInt16Func( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int16_t * buffer, const int16_t * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadInt16;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_int16 = buffer;
+ sd->audiothread_command_inputBuffer.buf_int16 = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessInt16Func( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessInt24Func( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, OpenMPT_int24 * buffer, const OpenMPT_int24 * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadInt24;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_int24 = buffer;
+ sd->audiothread_command_inputBuffer.buf_int24 = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessInt24Func( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessInt32Func( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, int32_t * buffer, const int32_t * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadInt32;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_int32 = buffer;
+ sd->audiothread_command_inputBuffer.buf_int32 = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessInt32Func( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessFloatFunc( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, float * buffer, const float * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadFloat;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_float = buffer;
+ sd->audiothread_command_inputBuffer.buf_float = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessFloatFunc( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessDoubleFunc( void * inst, const OpenMPT_SoundDevice_BufferFormat * bufferFormat, uintptr_t numFrames, double * buffer, const double * inputBuffer ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadDouble;
+ sd->audiothread_command_bufferFormat = bufferFormat;
+ sd->audiothread_command_numFrames = numFrames;
+ sd->audiothread_command_buffer.buf_double = buffer;
+ sd->audiothread_command_inputBuffer.buf_double = inputBuffer;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessDoubleFunc( sd->wine_callback.inst, bufferFormat, bufferAttributes, numFrames, buffer, inputBuffer );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackLockedProcessDoneFunc( void * inst, const OpenMPT_SoundDevice_TimeInfo * timeInfo ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandReadDone;
+ sd->audiothread_command_timeInfo = timeInfo;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackLockedProcessDoneFunc( sd->wine_callback.inst, timeInfo );
+#endif
+}
+static void OPENMPT_WINESUPPORT_CALL SoundCallbackUnlockFunc( void * inst ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)inst;
+ if ( !sd ) {
+ return;
+ }
+#ifdef WINE_THREAD
+ sd->audiothread_command = AudioThreadCommandUnlock;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+#else
+ return sd->wine_callback.SoundCallbackUnlockFunc( sd->wine_callback.inst );
+#endif
+}
+
+#ifdef WINE_THREAD
+static DWORD WINAPI AudioThread( LPVOID userdata ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)userdata;
+ sd->priority_booster = OpenMPT_PriorityBooster_Construct_From_SoundDevice( sd->impl );
+ SetEvent( sd->audiothread_startup_done );
+ {
+ int exit = 0;
+ while(!exit)
+ {
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_request );
+ switch ( sd->audiothread_command ) {
+ case AudioThreadCommandExit:
+ exit = 1;
+ break;
+ case AudioThreadCommandLock:
+ if(sd->wine_callback.SoundCallbackLockFunc)
+ sd->wine_callback.SoundCallbackLockFunc( sd->wine_callback.inst );
+ break;
+ case AudioThreadCommandClock:
+ if(sd->wine_callback.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc)
+ sd->wine_callback.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc( sd->wine_callback.inst, sd->audiothread_command_result );
+ break;
+ case AudioThreadCommandReadPrepare:
+ if(sd->wine_callback.SoundCallbackLockedProcessPrepareFunc)
+ sd->wine_callback.SoundCallbackLockedProcessPrepareFunc
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_timeInfo
+ );
+ break;
+ case AudioThreadCommandReadUint8:
+ if(sd->wine_callback.SoundCallbackLockedProcessUint8Func)
+ sd->wine_callback.SoundCallbackLockedProcessUint8Func
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_uint8
+ , sd->audiothread_command_inputBuffer.buf_uint8
+ );
+ break;
+ case AudioThreadCommandReadInt8:
+ if(sd->wine_callback.SoundCallbackLockedProcessInt8Func)
+ sd->wine_callback.SoundCallbackLockedProcessInt8Func
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_int8
+ , sd->audiothread_command_inputBuffer.buf_int8
+ );
+ break;
+ case AudioThreadCommandReadInt16:
+ if(sd->wine_callback.SoundCallbackLockedProcessInt16Func)
+ sd->wine_callback.SoundCallbackLockedProcessInt16Func
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_int16
+ , sd->audiothread_command_inputBuffer.buf_int16
+ );
+ break;
+ case AudioThreadCommandReadInt24:
+ if(sd->wine_callback.SoundCallbackLockedProcessInt24Func)
+ sd->wine_callback.SoundCallbackLockedProcessInt24Func
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_int24
+ , sd->audiothread_command_inputBuffer.buf_int24
+ );
+ break;
+ case AudioThreadCommandReadInt32:
+ if(sd->wine_callback.SoundCallbackLockedProcessInt32Func)
+ sd->wine_callback.SoundCallbackLockedProcessInt32Func
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_int32
+ , sd->audiothread_command_inputBuffer.buf_int32
+ );
+ break;
+ case AudioThreadCommandReadFloat:
+ if(sd->wine_callback.SoundCallbackLockedProcessFloatFunc)
+ sd->wine_callback.SoundCallbackLockedProcessFloatFunc
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_float
+ , sd->audiothread_command_inputBuffer.buf_float
+ );
+ break;
+ case AudioThreadCommandReadDouble:
+ if(sd->wine_callback.SoundCallbackLockedProcessDoubleFunc)
+ sd->wine_callback.SoundCallbackLockedProcessDoubleFunc
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_bufferFormat
+ , sd->audiothread_command_numFrames
+ , sd->audiothread_command_buffer.buf_double
+ , sd->audiothread_command_inputBuffer.buf_double
+ );
+ break;
+ case AudioThreadCommandReadDone:
+ if(sd->wine_callback.SoundCallbackLockedProcessDoneFunc)
+ sd->wine_callback.SoundCallbackLockedProcessDoneFunc
+ ( sd->wine_callback.inst
+ , sd->audiothread_command_timeInfo
+ );
+ break;
+ case AudioThreadCommandUnlock:
+ if(sd->wine_callback.SoundCallbackUnlockFunc)
+ sd->wine_callback.SoundCallbackUnlockFunc( sd->wine_callback.inst );
+ break;
+ default:
+ break;
+ }
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_done );
+ }
+ }
+ OpenMPT_PriorityBooster_Destruct(sd->priority_booster);
+ sd->priority_booster = NULL;
+ return 0;
+}
+#endif
+
+OPENMPT_WINESUPPORT_WRAPPER_API OpenMPT_Wine_Wrapper_SoundDevice * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Construct( const char * info ) {
+ OpenMPT_Wine_Wrapper_SoundDevice * sd = (OpenMPT_Wine_Wrapper_SoundDevice*)OpenMPT_Wine_Wrapper_Alloc( sizeof( OpenMPT_Wine_Wrapper_SoundDevice ) );
+ sd->impl = OpenMPT_SoundDevice_Construct( info );
+ return sd;
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Destruct( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ OpenMPT_SoundDevice_Destruct( sd->impl );
+ sd->impl = NULL;
+ OpenMPT_Wine_Wrapper_Free( sd );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_SetMessageReceiver( OpenMPT_Wine_Wrapper_SoundDevice * sd, const OpenMPT_Wine_Wrapper_SoundDevice_IMessageReceiver * receiver ) {
+ OpenMPT_SoundDevice_SetMessageReceiver( sd->impl, NULL );
+ ZeroMemory( &( sd->wine_receiver ), sizeof( sd->wine_receiver ) );
+ if(receiver)
+ {
+ sd->wine_receiver = *receiver;
+ }
+ sd->native_receiver.inst = sd;
+ sd->native_receiver.SoundDeviceMessageFunc = &SoundDeviceMessageFunc;
+ OpenMPT_SoundDevice_SetMessageReceiver( sd->impl, &sd->native_receiver );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_SetCallback( OpenMPT_Wine_Wrapper_SoundDevice * sd, const OpenMPT_Wine_Wrapper_SoundDevice_ICallback * callback ) {
+ OpenMPT_SoundDevice_SetCallback( sd->impl, NULL );
+ ZeroMemory( &( sd->wine_callback ), sizeof( sd->wine_callback) );
+ if(callback)
+ {
+ sd->wine_callback = *callback;
+ }
+ sd->native_callback.inst = sd;
+ sd->native_callback.SoundCallbackGetReferenceClockNowNanosecondsFunc = &SoundCallbackGetReferenceClockNowNanosecondsFunc;
+ sd->native_callback.SoundCallbackPreStartFunc = &SoundCallbackPreStartFunc;
+ sd->native_callback.SoundCallbackPostStopFunc = &SoundCallbackPostStopFunc;
+ sd->native_callback.SoundCallbackIsLockedByCurrentThreadFunc = &SoundCallbackIsLockedByCurrentThreadFunc;
+ sd->native_callback.SoundCallbackLockFunc = &SoundCallbackLockFunc;
+ sd->native_callback.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc = &SoundCallbackLockedGetReferenceClockNowNanosecondsFunc;
+ sd->native_callback.SoundCallbackLockedProcessPrepareFunc = &SoundCallbackLockedProcessPrepareFunc;
+ sd->native_callback.SoundCallbackLockedProcessUint8Func = &SoundCallbackLockedProcessUint8Func;
+ sd->native_callback.SoundCallbackLockedProcessInt8Func = &SoundCallbackLockedProcessInt8Func;
+ sd->native_callback.SoundCallbackLockedProcessInt16Func = &SoundCallbackLockedProcessInt16Func;
+ sd->native_callback.SoundCallbackLockedProcessInt24Func = &SoundCallbackLockedProcessInt24Func;
+ sd->native_callback.SoundCallbackLockedProcessInt32Func = &SoundCallbackLockedProcessInt32Func;
+ sd->native_callback.SoundCallbackLockedProcessFloatFunc = &SoundCallbackLockedProcessFloatFunc;
+ sd->native_callback.SoundCallbackLockedProcessDoubleFunc = &SoundCallbackLockedProcessDoubleFunc;
+ sd->native_callback.SoundCallbackLockedProcessDoneFunc = &SoundCallbackLockedProcessDoneFunc;
+ sd->native_callback.SoundCallbackUnlockFunc = &SoundCallbackUnlockFunc;
+ OpenMPT_SoundDevice_SetCallback( sd->impl, &sd->native_callback );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetDeviceInfo( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_GetDeviceInfo( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetDeviceCaps( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_GetDeviceCaps( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetDeviceDynamicCaps( OpenMPT_Wine_Wrapper_SoundDevice * sd, const char * baseSampleRates ) {
+ return OpenMPT_SoundDevice_GetDeviceDynamicCaps( sd->impl, baseSampleRates );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Init( OpenMPT_Wine_Wrapper_SoundDevice * sd, const char * appInfo ) {
+ return OpenMPT_SoundDevice_Init( sd->impl, appInfo );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Open( OpenMPT_Wine_Wrapper_SoundDevice * sd, const char * settings ) {
+ uintptr_t result = 0;
+ result = OpenMPT_SoundDevice_Open( sd->impl, settings );
+#ifdef WINE_THREAD
+ if ( result ) {
+ DWORD threadId = 0;
+ sd->audiothread_startup_done = CreateEvent( NULL, FALSE, FALSE, NULL );
+ sd->audiothread_sem_request = OpenMPT_Semaphore_Construct();
+ sd->audiothread_sem_done = OpenMPT_Semaphore_Construct();
+ sd->audiothread_command = AudioThreadCommandInvalid;
+ sd->audiothread = CreateThread( NULL, 0, &AudioThread, sd, 0, &threadId );
+ WaitForSingleObject( sd->audiothread_startup_done, INFINITE );
+ }
+#endif
+ return result;
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Close( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ uintptr_t result = 0;
+#ifdef WINE_THREAD
+ if ( OpenMPT_SoundDevice_IsOpen( sd->impl ) ) {
+ sd->audiothread_command = AudioThreadCommandExit;
+ OpenMPT_Semaphore_Post( sd->audiothread_sem_request );
+ OpenMPT_Semaphore_Wait( sd->audiothread_sem_done );
+ sd->audiothread_command = AudioThreadCommandInvalid;
+ WaitForSingleObject( sd->audiothread, INFINITE );
+ CloseHandle( sd->audiothread );
+ sd->audiothread = NULL;
+ OpenMPT_Semaphore_Destruct( sd->audiothread_sem_done );
+ sd->audiothread_sem_done = NULL;
+ OpenMPT_Semaphore_Destruct( sd->audiothread_sem_request );
+ sd->audiothread_sem_request = NULL;
+ CloseHandle( sd->audiothread_startup_done );
+ sd->audiothread_startup_done = NULL;
+ }
+#endif
+ result = OpenMPT_SoundDevice_Close( sd->impl );
+ return result;
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Start( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_Start( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_Stop( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_Stop( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetRequestFlags( const OpenMPT_Wine_Wrapper_SoundDevice * sd, uint32_t * result) {
+ return OpenMPT_SoundDevice_GetRequestFlags( sd->impl, result );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_IsInited( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_IsInited( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_IsOpen( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_IsOpen( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_IsAvailable( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_IsAvailable( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_IsPlaying( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_IsPlaying( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_IsPlayingSilence( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_IsPlayingSilence( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_StopAndAvoidPlayingSilence( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_StopAndAvoidPlayingSilence( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_EndPlayingSilence( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_EndPlayingSilence( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_OnIdle( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_OnIdle( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetSettings( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_GetSettings( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetActualSampleFormat( const OpenMPT_Wine_Wrapper_SoundDevice * sd, int32_t * result ) {
+ return OpenMPT_SoundDevice_GetActualSampleFormat( sd->impl, result );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetEffectiveBufferAttributes( const OpenMPT_Wine_Wrapper_SoundDevice * sd, OpenMPT_SoundDevice_BufferAttributes * result ) {
+ return OpenMPT_SoundDevice_GetEffectiveBufferAttributes( sd->impl, result );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetTimeInfo( const OpenMPT_Wine_Wrapper_SoundDevice * sd, OpenMPT_SoundDevice_TimeInfo * result ) {
+ return OpenMPT_SoundDevice_GetTimeInfo( sd->impl, result );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API void OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetStreamPosition( const OpenMPT_Wine_Wrapper_SoundDevice * sd, OpenMPT_SoundDevice_StreamPosition * result ) {
+ return OpenMPT_SoundDevice_GetStreamPosition( sd->impl, result );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_DebugIsFragileDevice( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_DebugIsFragileDevice( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_DebugInRealtimeCallback( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_DebugInRealtimeCallback( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API char * OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_GetStatistics( const OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_GetStatistics( sd->impl );
+}
+
+OPENMPT_WINESUPPORT_WRAPPER_API uintptr_t OPENMPT_WINESUPPORT_WRAPPER_CALL OpenMPT_Wine_Wrapper_SoundDevice_OpenDriverSettings( OpenMPT_Wine_Wrapper_SoundDevice * sd ) {
+ return OpenMPT_SoundDevice_OpenDriverSettings( sd->impl );
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // MPT_BUILD_WINESUPPORT_WRAPPER
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.cpp
new file mode 100644
index 00000000..e4709c8c
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/wine/WineWrapper.cpp
@@ -0,0 +1,6 @@
+
+#if defined(MPT_BUILD_WINESUPPORT_WRAPPER)
+
+#include "WineWrapper.c"
+
+#endif // MPT_BUILD_WINESUPPORT_WRAPPER