Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View 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"

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,6 @@
#if defined(MPT_BUILD_WINESUPPORT_WRAPPER)
#include "WineWrapper.c"
#endif // MPT_BUILD_WINESUPPORT_WRAPPER