NativeSoundDevice.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #include "stdafx.h"
  2. #if MPT_COMPILER_MSVC
  3. #pragma warning(disable:4800) // 'T' : forcing value to bool 'true' or 'false' (performance warning)
  4. #endif // MPT_COMPILER_MSVC
  5. #include "NativeSoundDevice.h"
  6. #include "NativeUtils.h"
  7. #include "openmpt/sounddevice/SoundDevice.hpp"
  8. #include "openmpt/sounddevice/SoundDeviceManager.hpp"
  9. #include "openmpt/sounddevice/SoundDeviceUtilities.hpp"
  10. #include "../../common/ComponentManager.h"
  11. #include "../../misc/mptOS.h"
  12. #include "NativeSoundDeviceMarshalling.h"
  13. #include <string>
  14. #include <type_traits>
  15. #include <cstdint>
  16. #include <cstdlib>
  17. #include <cstring>
  18. #include <stdint.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. OPENMPT_NAMESPACE_BEGIN
  22. namespace C {
  23. class ComponentSoundDeviceManager
  24. : public ComponentBuiltin
  25. {
  26. MPT_DECLARE_COMPONENT_MEMBERS(ComponentSoundDeviceManager, "SoundDeviceManager")
  27. private:
  28. mpt::log::GlobalLogger logger;
  29. SoundDevice::Manager manager;
  30. private:
  31. static SoundDevice::SysInfo GetSysInfo()
  32. {
  33. mpt::OS::Wine::VersionContext wineVersionContext;
  34. return SoundDevice::SysInfo(mpt::osinfo::get_class(), mpt::OS::Windows::Version::Current(), mpt::OS::Windows::IsWine(), wineVersionContext.HostClass(), wineVersionContext.Version());
  35. }
  36. public:
  37. ComponentSoundDeviceManager()
  38. : manager(logger, GetSysInfo(), SoundDevice::AppInfo())
  39. {
  40. return;
  41. }
  42. virtual ~ComponentSoundDeviceManager() { }
  43. bool DoInitialize() override
  44. {
  45. return true;
  46. }
  47. SoundDevice::Manager & get() const
  48. {
  49. return const_cast<SoundDevice::Manager &>(manager);
  50. }
  51. };
  52. static mpt::ustring GetTypePrefix()
  53. {
  54. return U_("Native");
  55. }
  56. static SoundDevice::Info AddTypePrefix(SoundDevice::Info info)
  57. {
  58. info.type = GetTypePrefix() + U_("-") + info.type;
  59. info.apiPath.insert(info.apiPath.begin(), U_("Native"));
  60. return info;
  61. }
  62. static SoundDevice::Info RemoveTypePrefix(SoundDevice::Info info)
  63. {
  64. info.type = info.type.substr(GetTypePrefix().length() + 1);
  65. info.apiPath.erase(info.apiPath.begin());
  66. return info;
  67. }
  68. std::string SoundDevice_EnumerateDevices()
  69. {
  70. ComponentHandle<ComponentSoundDeviceManager> manager;
  71. if(!IsComponentAvailable(manager))
  72. {
  73. return std::string();
  74. }
  75. std::vector<SoundDevice::Info> infos = std::vector<SoundDevice::Info>(manager->get().begin(), manager->get().end());
  76. for(auto &info : infos)
  77. {
  78. info = AddTypePrefix(info);
  79. }
  80. return json_cast<std::string>(infos);
  81. }
  82. SoundDevice::IBase * SoundDevice_Construct(std::string info_)
  83. {
  84. MPT_LOG_GLOBAL(LogDebug, "NativeSupport", MPT_UFORMAT("Contruct: {}")(mpt::ToUnicode(mpt::Charset::UTF8, info_)));
  85. ComponentHandle<ComponentSoundDeviceManager> manager;
  86. if(!IsComponentAvailable(manager))
  87. {
  88. return nullptr;
  89. }
  90. SoundDevice::Info info = json_cast<SoundDevice::Info>(info_);
  91. info = RemoveTypePrefix(info);
  92. return manager->get().CreateSoundDevice(info.GetIdentifier());
  93. }
  94. class NativeMessageReceiverProxy
  95. : public SoundDevice::IMessageReceiver
  96. {
  97. private:
  98. OpenMPT_SoundDevice_IMessageReceiver impl;
  99. public:
  100. NativeMessageReceiverProxy(const OpenMPT_SoundDevice_IMessageReceiver * impl_)
  101. {
  102. MemsetZero(impl);
  103. if(impl_)
  104. {
  105. impl = *impl_;
  106. }
  107. }
  108. virtual ~NativeMessageReceiverProxy()
  109. {
  110. return;
  111. }
  112. public:
  113. virtual void SoundDeviceMessage(LogLevel level, const mpt::ustring &str)
  114. {
  115. if(!impl.SoundDeviceMessageFunc)
  116. {
  117. return;
  118. }
  119. return impl.SoundDeviceMessageFunc(impl.inst, level, mpt::ToCharset(mpt::Charset::UTF8, str).c_str());
  120. }
  121. };
  122. class NativeCallbackProxy
  123. : public SoundDevice::ICallback
  124. {
  125. private:
  126. OpenMPT_SoundDevice_ICallback impl;
  127. public:
  128. NativeCallbackProxy(const OpenMPT_SoundDevice_ICallback * impl_)
  129. {
  130. MemsetZero(impl);
  131. if(impl_)
  132. {
  133. impl = *impl_;
  134. }
  135. }
  136. virtual ~NativeCallbackProxy()
  137. {
  138. return;
  139. }
  140. public:
  141. // main thread
  142. virtual uint64 SoundCallbackGetReferenceClockNowNanoseconds() const
  143. {
  144. if(!impl.SoundCallbackGetReferenceClockNowNanosecondsFunc)
  145. {
  146. return 0;
  147. }
  148. uint64_t result = 0;
  149. impl.SoundCallbackGetReferenceClockNowNanosecondsFunc(impl.inst, &result);
  150. return result;
  151. }
  152. virtual void SoundCallbackPreStart()
  153. {
  154. if(!impl.SoundCallbackPreStartFunc)
  155. {
  156. return;
  157. }
  158. return impl.SoundCallbackPreStartFunc(impl.inst);
  159. }
  160. virtual void SoundCallbackPostStop()
  161. {
  162. if(!impl.SoundCallbackPostStopFunc)
  163. {
  164. return;
  165. }
  166. return impl.SoundCallbackPostStopFunc(impl.inst);
  167. }
  168. virtual bool SoundCallbackIsLockedByCurrentThread() const
  169. {
  170. if(!impl.SoundCallbackIsLockedByCurrentThreadFunc)
  171. {
  172. return 0;
  173. }
  174. uintptr_t result = 0;
  175. impl.SoundCallbackIsLockedByCurrentThreadFunc(impl.inst, &result);
  176. return result;
  177. }
  178. // audio thread
  179. virtual void SoundCallbackLock()
  180. {
  181. if(!impl.SoundCallbackLockFunc)
  182. {
  183. return;
  184. }
  185. return impl.SoundCallbackLockFunc(impl.inst);
  186. }
  187. virtual uint64 SoundCallbackLockedGetReferenceClockNowNanoseconds() const
  188. {
  189. if(!impl.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc)
  190. {
  191. return 0;
  192. }
  193. uint64_t result = 0;
  194. impl.SoundCallbackLockedGetReferenceClockNowNanosecondsFunc(impl.inst, &result);
  195. return result;
  196. }
  197. virtual void SoundCallbackLockedProcessPrepare(SoundDevice::TimeInfo timeInfo)
  198. {
  199. if(!impl.SoundCallbackLockedProcessPrepareFunc)
  200. {
  201. return;
  202. }
  203. OpenMPT_SoundDevice_TimeInfo c_timeInfo = C::encode(timeInfo);
  204. return impl.SoundCallbackLockedProcessPrepareFunc(impl.inst, &c_timeInfo);
  205. }
  206. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, uint8 *buffer, const uint8 *inputBuffer)
  207. {
  208. if(!impl.SoundCallbackLockedProcessUint8Func)
  209. {
  210. return;
  211. }
  212. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  213. return impl.SoundCallbackLockedProcessUint8Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  214. }
  215. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int8 *buffer, const int8 *inputBuffer)
  216. {
  217. if(!impl.SoundCallbackLockedProcessInt8Func)
  218. {
  219. return;
  220. }
  221. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  222. return impl.SoundCallbackLockedProcessInt8Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  223. }
  224. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int16 *buffer, const int16 *inputBuffer)
  225. {
  226. if(!impl.SoundCallbackLockedProcessInt16Func)
  227. {
  228. return;
  229. }
  230. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  231. return impl.SoundCallbackLockedProcessInt16Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  232. }
  233. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int24 *buffer, const int24 *inputBuffer)
  234. {
  235. if(!impl.SoundCallbackLockedProcessInt24Func)
  236. {
  237. return;
  238. }
  239. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  240. return impl.SoundCallbackLockedProcessInt24Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  241. }
  242. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, int32 *buffer, const int32 *inputBuffer)
  243. {
  244. if(!impl.SoundCallbackLockedProcessInt32Func)
  245. {
  246. return;
  247. }
  248. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  249. return impl.SoundCallbackLockedProcessInt32Func(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  250. }
  251. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, float *buffer, const float *inputBuffer)
  252. {
  253. if(!impl.SoundCallbackLockedProcessFloatFunc)
  254. {
  255. return;
  256. }
  257. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  258. return impl.SoundCallbackLockedProcessFloatFunc(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  259. }
  260. virtual void SoundCallbackLockedProcess(SoundDevice::BufferFormat bufferFormat, std::size_t numFrames, double *buffer, const double *inputBuffer)
  261. {
  262. if(!impl.SoundCallbackLockedProcessDoubleFunc)
  263. {
  264. return;
  265. }
  266. OpenMPT_SoundDevice_BufferFormat c_bufferFormat = C::encode(bufferFormat);
  267. return impl.SoundCallbackLockedProcessDoubleFunc(impl.inst, &c_bufferFormat, numFrames, buffer, inputBuffer);
  268. }
  269. virtual void SoundCallbackLockedProcessDone(SoundDevice::TimeInfo timeInfo)
  270. {
  271. if(!impl.SoundCallbackLockedProcessDoneFunc)
  272. {
  273. return;
  274. }
  275. OpenMPT_SoundDevice_TimeInfo c_timeInfo = C::encode(timeInfo);
  276. return impl.SoundCallbackLockedProcessDoneFunc(impl.inst, &c_timeInfo);
  277. }
  278. virtual void SoundCallbackUnlock()
  279. {
  280. if(!impl.SoundCallbackUnlockFunc)
  281. {
  282. return;
  283. }
  284. return impl.SoundCallbackUnlockFunc(impl.inst);
  285. }
  286. };
  287. } // namespace C
  288. OPENMPT_NAMESPACE_END
  289. extern "C" {
  290. struct OpenMPT_SoundDevice {
  291. OPENMPT_NAMESPACE::SoundDevice::IBase * impl;
  292. OPENMPT_NAMESPACE::C::NativeMessageReceiverProxy * messageReceiver;
  293. OPENMPT_NAMESPACE::C::NativeCallbackProxy * callback;
  294. };
  295. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EnumerateDevices() {
  296. return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::C::SoundDevice_EnumerateDevices().c_str() );
  297. }
  298. OPENMPT_WINESUPPORT_API OpenMPT_SoundDevice * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Construct( const char * info ) {
  299. if ( !info ) {
  300. return nullptr;
  301. }
  302. OpenMPT_SoundDevice * result = reinterpret_cast< OpenMPT_SoundDevice * >( OpenMPT_Alloc( sizeof( OpenMPT_SoundDevice ) ) );
  303. if ( !result ) {
  304. return nullptr;
  305. }
  306. result->impl = OPENMPT_NAMESPACE::C::SoundDevice_Construct( info );
  307. if ( !result->impl ) {
  308. OpenMPT_Free( result );
  309. return nullptr;
  310. }
  311. return result;
  312. }
  313. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Destruct( OpenMPT_SoundDevice * sd ) {
  314. if ( sd ) {
  315. if ( sd->impl ) {
  316. sd->impl->SetMessageReceiver( nullptr );
  317. delete sd->messageReceiver;
  318. sd->messageReceiver = nullptr;
  319. delete sd->impl;
  320. sd->impl = nullptr;
  321. }
  322. OpenMPT_Free( sd );
  323. }
  324. }
  325. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetMessageReceiver( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_IMessageReceiver * receiver ) {
  326. if ( !sd ) {
  327. return;
  328. }
  329. if ( !sd->impl ) {
  330. return;
  331. }
  332. sd->impl->SetMessageReceiver( nullptr );
  333. delete sd->messageReceiver;
  334. sd->messageReceiver = nullptr;
  335. sd->messageReceiver = new OPENMPT_NAMESPACE::C::NativeMessageReceiverProxy( receiver );
  336. sd->impl->SetMessageReceiver( sd->messageReceiver );
  337. return;
  338. }
  339. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_SetCallback( OpenMPT_SoundDevice * sd, const OpenMPT_SoundDevice_ICallback * callback ) {
  340. if ( !sd ) {
  341. return;
  342. }
  343. if ( !sd->impl ) {
  344. return;
  345. }
  346. sd->impl->SetCallback( nullptr );
  347. delete sd->callback;
  348. sd->callback = nullptr;
  349. sd->callback = new OPENMPT_NAMESPACE::C::NativeCallbackProxy( callback );
  350. sd->impl->SetCallback( sd->callback );
  351. return;
  352. }
  353. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceInfo( const OpenMPT_SoundDevice * sd ) {
  354. OPENMPT_NAMESPACE::SoundDevice::Info info = sd->impl->GetDeviceInfo();
  355. info = OPENMPT_NAMESPACE::C::AddTypePrefix(info);
  356. return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetDeviceInfo() ).c_str() );
  357. }
  358. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceCaps( const OpenMPT_SoundDevice * sd ) {
  359. return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetDeviceCaps() ).c_str() );
  360. }
  361. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetDeviceDynamicCaps( OpenMPT_SoundDevice * sd, const char * baseSampleRates ) {
  362. 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() );
  363. }
  364. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Init( OpenMPT_SoundDevice * sd, const char * appInfo ) {
  365. return sd->impl->Init( OPENMPT_NAMESPACE::json_cast<OPENMPT_NAMESPACE::SoundDevice::AppInfo>( std::string(appInfo) ) );
  366. }
  367. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Open( OpenMPT_SoundDevice * sd, const char * settings ) {
  368. return sd->impl->Open( OPENMPT_NAMESPACE::json_cast<OPENMPT_NAMESPACE::SoundDevice::Settings>( std::string(settings) ) );
  369. }
  370. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Close( OpenMPT_SoundDevice * sd ) {
  371. return sd->impl->Close();
  372. }
  373. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Start( OpenMPT_SoundDevice * sd ) {
  374. return sd->impl->Start();
  375. }
  376. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_Stop( OpenMPT_SoundDevice * sd ) {
  377. return sd->impl->Stop();
  378. }
  379. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetRequestFlags( const OpenMPT_SoundDevice * sd, uint32_t * result) {
  380. *result = sd->impl->GetRequestFlags().GetRaw();
  381. }
  382. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsInited( const OpenMPT_SoundDevice * sd ) {
  383. return sd->impl->IsInited();
  384. }
  385. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsOpen( const OpenMPT_SoundDevice * sd ) {
  386. return sd->impl->IsOpen();
  387. }
  388. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsAvailable( const OpenMPT_SoundDevice * sd ) {
  389. return sd->impl->IsAvailable();
  390. }
  391. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlaying( const OpenMPT_SoundDevice * sd ) {
  392. return sd->impl->IsPlaying();
  393. }
  394. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_IsPlayingSilence( const OpenMPT_SoundDevice * sd ) {
  395. return sd->impl->IsPlayingSilence();
  396. }
  397. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_StopAndAvoidPlayingSilence( OpenMPT_SoundDevice * sd ) {
  398. return sd->impl->StopAndAvoidPlayingSilence();
  399. }
  400. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_EndPlayingSilence( OpenMPT_SoundDevice * sd ) {
  401. return sd->impl->EndPlayingSilence();
  402. }
  403. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OnIdle( OpenMPT_SoundDevice * sd ) {
  404. return sd->impl->OnIdle();
  405. }
  406. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetSettings( const OpenMPT_SoundDevice * sd ) {
  407. return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetSettings() ).c_str() );
  408. }
  409. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetActualSampleFormat( const OpenMPT_SoundDevice * sd, int32_t * result ) {
  410. *result = OPENMPT_NAMESPACE::mpt::to_underlying<OPENMPT_NAMESPACE::SampleFormat::Enum>(sd->impl->GetActualSampleFormat());
  411. }
  412. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetEffectiveBufferAttributes( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_BufferAttributes * result ) {
  413. *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetEffectiveBufferAttributes() );
  414. }
  415. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetTimeInfo( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_TimeInfo * result ) {
  416. *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetTimeInfo() );
  417. }
  418. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStreamPosition( const OpenMPT_SoundDevice * sd, OpenMPT_SoundDevice_StreamPosition * result ) {
  419. *result = OPENMPT_NAMESPACE::C::encode( sd->impl->GetStreamPosition() );
  420. }
  421. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugIsFragileDevice( const OpenMPT_SoundDevice * sd ) {
  422. return sd->impl->DebugIsFragileDevice();
  423. }
  424. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_DebugInRealtimeCallback( const OpenMPT_SoundDevice * sd ) {
  425. return sd->impl->DebugInRealtimeCallback();
  426. }
  427. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_GetStatistics( const OpenMPT_SoundDevice * sd ) {
  428. return OpenMPT_String_Duplicate( OPENMPT_NAMESPACE::json_cast<std::string>( sd->impl->GetStatistics() ).c_str() );
  429. }
  430. OPENMPT_WINESUPPORT_API uintptr_t OPENMPT_WINESUPPORT_CALL OpenMPT_SoundDevice_OpenDriverSettings( OpenMPT_SoundDevice * sd ) {
  431. return sd->impl->OpenDriverSettings();
  432. }
  433. typedef struct OpenMPT_PriorityBooster {
  434. #ifndef _MSC_VER
  435. OPENMPT_NAMESPACE::SoundDevice::ThreadPriorityGuard * impl;
  436. #else
  437. void * dummy;
  438. #endif
  439. } OpenMPT_PriorityBooster;
  440. OPENMPT_WINESUPPORT_API OpenMPT_PriorityBooster * OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Construct_From_SoundDevice( const OpenMPT_SoundDevice * sd ) {
  441. #if !MPT_OS_WINDOWS
  442. OpenMPT_PriorityBooster * pb = (OpenMPT_PriorityBooster*)OpenMPT_Alloc( sizeof( OpenMPT_PriorityBooster ) );
  443. pb->impl = new OPENMPT_NAMESPACE::SoundDevice::ThreadPriorityGuard
  444. ( dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetLogger()
  445. , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetSettings().BoostThreadPriority
  446. , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadRealtimePosix
  447. , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadNicenessPosix
  448. , dynamic_cast<OPENMPT_NAMESPACE::SoundDevice::Base*>(sd->impl)->GetAppInfo().BoostedThreadRtprioPosix
  449. );
  450. return pb;
  451. #else
  452. MPT_UNREFERENCED_PARAMETER(sd);
  453. return nullptr;
  454. #endif
  455. }
  456. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_PriorityBooster_Destruct( OpenMPT_PriorityBooster * pb ) {
  457. #if !MPT_OS_WINDOWS
  458. delete pb->impl;
  459. pb->impl = nullptr;
  460. OpenMPT_Free( pb );
  461. #else
  462. MPT_UNREFERENCED_PARAMETER(pb);
  463. #endif
  464. }
  465. } // extern "C"