diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/wine | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/wine')
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 |