NativeSoundDeviceMarshalling.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #pragma once
  2. #include "openmpt/all/BuildSettings.hpp"
  3. #include "NativeSoundDevice.h"
  4. #include "openmpt/sounddevice/SoundDevice.hpp"
  5. #ifdef MPT_WITH_NLOHMANNJSON
  6. // https://github.com/nlohmann/json/issues/1204
  7. #if MPT_COMPILER_MSVC
  8. #pragma warning(push)
  9. #pragma warning(disable:4127) // conditional expression is constant
  10. #endif // MPT_COMPILER_MSVC
  11. #include "mpt/json/json.hpp"
  12. #if MPT_COMPILER_MSVC
  13. #pragma warning(pop)
  14. #endif // MPT_COMPILER_MSVC
  15. #endif // MPT_WITH_NLOHMANNJSON
  16. OPENMPT_NAMESPACE_BEGIN
  17. #ifdef MPT_WITH_NLOHMANNJSON
  18. inline void to_json(nlohmann::json &j, const SampleFormat &val)
  19. {
  20. j = SampleFormat::ToInt(val);
  21. }
  22. inline void from_json(const nlohmann::json &j, SampleFormat &val)
  23. {
  24. val = SampleFormat::FromInt(j);
  25. }
  26. namespace SoundDevice
  27. {
  28. inline void to_json(nlohmann::json &j, const SoundDevice::ChannelMapping &val)
  29. {
  30. j = val.ToUString();
  31. }
  32. inline void from_json(const nlohmann::json &j, SoundDevice::ChannelMapping &val)
  33. {
  34. val = SoundDevice::ChannelMapping::FromString(j);
  35. }
  36. inline void to_json(nlohmann::json &j, const SoundDevice::Info::Default &val)
  37. {
  38. j = static_cast<int>(val);
  39. }
  40. inline void from_json(const nlohmann::json &j, SoundDevice::Info::Default &val)
  41. {
  42. val = static_cast<SoundDevice::Info::Default>(static_cast<int>(j));
  43. }
  44. } // namespace SoundDevice
  45. namespace SoundDevice
  46. {
  47. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::ManagerFlags
  48. ,defaultFor
  49. )
  50. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::Flags
  51. ,usability
  52. ,level
  53. ,compatible
  54. ,api
  55. ,io
  56. ,mixing
  57. ,implementor
  58. )
  59. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info
  60. ,type
  61. ,internalID
  62. ,name
  63. ,apiName
  64. ,apiPath
  65. ,default_
  66. ,useNameAsIdentifier
  67. ,managerFlags
  68. ,flags
  69. ,extraData
  70. )
  71. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::AppInfo
  72. ,Name
  73. ,BoostedThreadPriorityXP
  74. ,BoostedThreadMMCSSClassVista
  75. ,BoostedThreadRealtimePosix
  76. ,BoostedThreadNicenessPosix
  77. ,BoostedThreadRtprioPosix
  78. ,MaskDriverCrashes
  79. ,AllowDeferredProcessing
  80. )
  81. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Settings
  82. ,Latency
  83. ,UpdateInterval
  84. ,Samplerate
  85. ,Channels
  86. ,InputChannels
  87. ,sampleFormat
  88. ,ExclusiveMode
  89. ,BoostThreadPriority
  90. ,KeepDeviceRunning
  91. ,UseHardwareTiming
  92. ,DitherType
  93. ,InputSourceID
  94. )
  95. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Caps
  96. ,Available
  97. ,CanUpdateInterval
  98. ,CanSampleFormat
  99. ,CanExclusiveMode
  100. ,CanBoostThreadPriority
  101. ,CanKeepDeviceRunning
  102. ,CanUseHardwareTiming
  103. ,CanChannelMapping
  104. ,CanInput
  105. ,HasNamedInputSources
  106. ,CanDriverPanel
  107. ,HasInternalDither
  108. ,ExclusiveModeDescription
  109. ,LatencyMin
  110. ,LatencyMax
  111. ,UpdateIntervalMin
  112. ,UpdateIntervalMax
  113. ,DefaultSettings
  114. )
  115. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::DynamicCaps
  116. ,currentSampleRate
  117. ,supportedSampleRates
  118. ,supportedExclusiveSampleRates
  119. ,supportedSampleFormats
  120. ,supportedExclusiveModeSampleFormats
  121. ,channelNames
  122. ,inputSourceNames
  123. )
  124. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Statistics
  125. ,InstantaneousLatency
  126. ,LastUpdateInterval
  127. ,text
  128. )
  129. } // namespace SoundDevice
  130. template <typename Tdst, typename Tsrc>
  131. struct json_cast_impl
  132. {
  133. Tdst operator () (const Tsrc &src);
  134. };
  135. template <typename Tdst, typename Tsrc>
  136. Tdst json_cast(const Tsrc &src)
  137. {
  138. return json_cast_impl<Tdst, Tsrc>()(src);
  139. }
  140. template <typename Tsrc>
  141. struct json_cast_impl<nlohmann::json, Tsrc>
  142. {
  143. nlohmann::json operator () (const Tsrc &src)
  144. {
  145. return static_cast<nlohmann::json>(src);
  146. }
  147. };
  148. template <typename Tdst>
  149. struct json_cast_impl<Tdst, nlohmann::json>
  150. {
  151. Tdst operator () (const nlohmann::json &src)
  152. {
  153. return src.get<Tdst>();
  154. }
  155. };
  156. template <typename Tsrc>
  157. struct json_cast_impl<std::string, Tsrc>
  158. {
  159. std::string operator () (const Tsrc &src)
  160. {
  161. return json_cast<nlohmann::json>(src).dump(4);
  162. }
  163. };
  164. template <typename Tdst>
  165. struct json_cast_impl<Tdst, std::string>
  166. {
  167. Tdst operator () (const std::string &str)
  168. {
  169. return json_cast<Tdst>(nlohmann::json::parse(str));
  170. }
  171. };
  172. #endif // MPT_WITH_NLOHMANNJSON
  173. namespace C {
  174. static_assert(sizeof(OpenMPT_SoundDevice_StreamPosition) % 8 == 0);
  175. inline OpenMPT_SoundDevice_StreamPosition encode(SoundDevice::StreamPosition src) {
  176. OpenMPT_SoundDevice_StreamPosition dst;
  177. MemsetZero(dst);
  178. dst.Frames = src.Frames;
  179. dst.Seconds = src.Seconds;
  180. return dst;
  181. }
  182. inline SoundDevice::StreamPosition decode(OpenMPT_SoundDevice_StreamPosition src) {
  183. SoundDevice::StreamPosition dst;
  184. dst.Frames = src.Frames;
  185. dst.Seconds = src.Seconds;
  186. return dst;
  187. }
  188. static_assert(sizeof(OpenMPT_SoundDevice_TimeInfo) % 8 == 0);
  189. inline OpenMPT_SoundDevice_TimeInfo encode(SoundDevice::TimeInfo src) {
  190. OpenMPT_SoundDevice_TimeInfo dst;
  191. MemsetZero(dst);
  192. dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
  193. dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
  194. dst.Speed = src.Speed;
  195. dst.RenderStreamPositionBefore = encode(src.RenderStreamPositionBefore);
  196. dst.RenderStreamPositionAfter = encode(src.RenderStreamPositionAfter);
  197. dst.Latency = src.Latency;
  198. return dst;
  199. }
  200. inline SoundDevice::TimeInfo decode(OpenMPT_SoundDevice_TimeInfo src) {
  201. SoundDevice::TimeInfo dst;
  202. dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
  203. dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
  204. dst.Speed = src.Speed;
  205. dst.RenderStreamPositionBefore = decode(src.RenderStreamPositionBefore);
  206. dst.RenderStreamPositionAfter = decode(src.RenderStreamPositionAfter);
  207. dst.Latency = src.Latency;
  208. return dst;
  209. }
  210. static_assert(sizeof(OpenMPT_SoundDevice_Flags) % 8 == 0);
  211. inline OpenMPT_SoundDevice_Flags encode(SoundDevice::Flags src) {
  212. OpenMPT_SoundDevice_Flags dst;
  213. MemsetZero(dst);
  214. dst.WantsClippedOutput = src.WantsClippedOutput;
  215. return dst;
  216. }
  217. inline SoundDevice::Flags decode(OpenMPT_SoundDevice_Flags src) {
  218. SoundDevice::Flags dst;
  219. dst.WantsClippedOutput = src.WantsClippedOutput;
  220. return dst;
  221. }
  222. static_assert(sizeof(OpenMPT_SoundDevice_BufferFormat) % 8 == 0);
  223. inline OpenMPT_SoundDevice_BufferFormat encode(SoundDevice::BufferFormat src) {
  224. OpenMPT_SoundDevice_BufferFormat dst;
  225. MemsetZero(dst);
  226. dst.Samplerate = src.Samplerate;
  227. dst.Channels = src.Channels;
  228. dst.InputChannels = src.InputChannels;
  229. dst.sampleFormat = SampleFormat::ToInt(src.sampleFormat);
  230. dst.WantsClippedOutput = src.WantsClippedOutput;
  231. dst.DitherType = src.DitherType;
  232. return dst;
  233. }
  234. inline SoundDevice::BufferFormat decode(OpenMPT_SoundDevice_BufferFormat src) {
  235. SoundDevice::BufferFormat dst;
  236. dst.Samplerate = src.Samplerate;
  237. dst.Channels = src.Channels;
  238. dst.InputChannels = src.InputChannels;
  239. dst.sampleFormat = SampleFormat::FromInt(src.sampleFormat);
  240. dst.WantsClippedOutput = src.WantsClippedOutput;
  241. dst.DitherType = src.DitherType;
  242. return dst;
  243. }
  244. static_assert(sizeof(OpenMPT_SoundDevice_BufferAttributes) % 8 == 0);
  245. inline OpenMPT_SoundDevice_BufferAttributes encode(SoundDevice::BufferAttributes src) {
  246. OpenMPT_SoundDevice_BufferAttributes dst;
  247. MemsetZero(dst);
  248. dst.Latency = src.Latency;
  249. dst.UpdateInterval = src.UpdateInterval;
  250. dst.NumBuffers = src.NumBuffers;
  251. return dst;
  252. }
  253. inline SoundDevice::BufferAttributes decode(OpenMPT_SoundDevice_BufferAttributes src) {
  254. SoundDevice::BufferAttributes dst;
  255. dst.Latency = src.Latency;
  256. dst.UpdateInterval = src.UpdateInterval;
  257. dst.NumBuffers = src.NumBuffers;
  258. return dst;
  259. }
  260. static_assert(sizeof(OpenMPT_SoundDevice_RequestFlags) % 8 == 0);
  261. inline OpenMPT_SoundDevice_RequestFlags encode(FlagSet<SoundDevice::RequestFlags> src) {
  262. OpenMPT_SoundDevice_RequestFlags dst;
  263. MemsetZero(dst);
  264. dst.RequestFlags = src.GetRaw();
  265. return dst;
  266. }
  267. inline FlagSet<SoundDevice::RequestFlags> decode(OpenMPT_SoundDevice_RequestFlags src) {
  268. FlagSet<SoundDevice::RequestFlags> dst;
  269. dst.SetRaw(src.RequestFlags);
  270. return dst;
  271. }
  272. } // namespace C
  273. OPENMPT_NAMESPACE_END