Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
103
Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp
Normal file
103
Src/external_dependencies/openmpt-trunk/mptrack/wine/Native.cpp
Normal file
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
#if defined(MPT_BUILD_WINESUPPORT_WRAPPER)
|
||||
|
||||
#include "WineWrapper.c"
|
||||
|
||||
#endif // MPT_BUILD_WINESUPPORT_WRAPPER
|
Loading…
Add table
Add a link
Reference in a new issue