SinkDevices.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*******************************************************************************
  2. The content of this file includes portions of the AUDIOKINETIC Wwise Technology
  3. released in source code form as part of the SDK installer package.
  4. Commercial License Usage
  5. Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
  6. may use this file in accordance with the end user license agreement provided
  7. with the software or, alternatively, in accordance with the terms contained in a
  8. written agreement between you and Audiokinetic Inc.
  9. Apache License Usage
  10. Alternatively, this file may be used under the Apache License, Version 2.0 (the
  11. "Apache License"); you may not use this file except in compliance with the
  12. Apache License. You may obtain a copy of the Apache License at
  13. http://www.apache.org/licenses/LICENSE-2.0.
  14. Unless required by applicable law or agreed to in writing, software distributed
  15. under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
  16. OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
  17. the specific language governing permissions and limitations under the License.
  18. Copyright (c) 2023 Audiokinetic Inc.
  19. *******************************************************************************/
  20. /**
  21. * \brief Wwise Authoring Plug-ins - Plug-in that lists supported output devices.
  22. * \file AK/Wwise/Plugin/SinkDevices.h
  23. *
  24. * Provides a list of up-to-date device IDs that can be used to instantiate a new Sound Engine sink.
  25. *
  26. * \sa C interfaces
  27. * - \ref ak_wwise_plugin_sink_devices_v1
  28. *
  29. * \sa C++ interfaces
  30. * - \ref AK::Wwise::Plugin::SinkDevices
  31. */
  32. #pragma once
  33. #include "PluginInfoGenerator.h"
  34. /**
  35. * \brief Device enumerator for sink plug-ins.
  36. *
  37. * Allows your plug-in to provide a list of up-to-date device IDs that can be used to instantiate a new
  38. * Sound Engine sink.
  39. *
  40. * This plug-in interface cannot be linked to a backend or a frontend plug-in, it must be standalone.
  41. *
  42. * \sa
  43. * - \ref ak_wwise_plugin_sink_devices_instance_v1 instance type
  44. * - \ref AK::Wwise::Plugin::SinkDevices C++ Interface
  45. * - \ref AK_WWISE_PLUGIN_SINK_DEVICES_V1_ID Current ID for interface
  46. * - \ref AK_WWISE_PLUGIN_INTERFACE_TYPE_SINK_DEVICES
  47. */
  48. struct ak_wwise_plugin_sink_devices_v1
  49. #ifdef __cplusplus
  50. : public ak_wwise_plugin_base_interface
  51. #endif
  52. {
  53. #ifndef __cplusplus
  54. ak_wwise_plugin_base_interface m_baseInterface;
  55. #endif
  56. #ifdef __cplusplus
  57. using Instance = ak_wwise_plugin_sink_devices_instance_v1; ///< \copydoc ak_wwise_plugin_sink_devices_instance_v1
  58. ak_wwise_plugin_sink_devices_v1() :
  59. ak_wwise_plugin_base_interface(AK_WWISE_PLUGIN_INTERFACE_TYPE_SINK_DEVICES, 1)
  60. {}
  61. #endif
  62. /**
  63. * \brief Get a count of the number of interfaces currently available.
  64. *
  65. * Provided by your plug-in, this should return a count.
  66. *
  67. * \aknote
  68. * Due to the unpredictable nature of hardware configuration changes, an unpadded, basic system would return
  69. * a configuration that can change between a GetCount and subsequent objects retrieval.
  70. *
  71. * As a plug-in designer, you are responsible to address this by returning adequate values that make sense as a whole.
  72. *
  73. * To guide you, Sink Devices interface is used for retrieval and data copy in a tight loop over a single thread
  74. * at once. Host will retrieve the count, followed by the Name (GetName) and DeviceID (GetDeviceID), in the
  75. * order the compiler sees fit. Data is expected to survive for the amount of time this tight loop exists.
  76. *
  77. * \code
  78. * int count = m_interface->GetCount(m_instance);
  79. * for (int i = 0; i < count; ++i)
  80. * {
  81. * result.emplace_back(
  82. * m_interface->GetName(m_instance, i),
  83. * m_interface->GetDeviceID(m_instance, i)
  84. * );
  85. * }
  86. * \endcode
  87. *
  88. * A proposal is to use GetCount to internally retrieve the device names and IDs, make a static internal
  89. * cache, and then return name and device ID based on this cache.
  90. *
  91. * You can also spawn an event listener or an update thread, and ensure the data is up to date when the calls
  92. * come in, and block updates until all calls are accounted for.
  93. * \endaknote
  94. *
  95. * \param[in] in_this Current instance of this interface.
  96. * \return int Count of the number of interfaces available.
  97. */
  98. int(*GetCount)(const struct ak_wwise_plugin_sink_devices_instance_v1* in_this);
  99. /**
  100. * \brief Get a user-presentable name for the device number in_num.
  101. *
  102. * Provided by your plug-in, this should return a const char* in UTF-8, valid at least until the next
  103. * function call, and must not return duplicates or nullptr.
  104. *
  105. * It should return names that can be understood by an end user in the context of your plug-in.
  106. *
  107. * \param[in] in_this Current instance of this interface.
  108. * \param[in] in_num Device number, from zero to the value, as retrieved by GetCount.
  109. * \return const char* UTF-8 Name of the interface in_num.
  110. *
  111. * \sa \ref GetCount for a discussion on providing data in a multithread-aware environment.
  112. */
  113. const char*(*GetName)(const struct ak_wwise_plugin_sink_devices_instance_v1* in_this, int in_num);
  114. /**
  115. * \brief Get a device ID for the device number in_num.
  116. *
  117. * Provided by your plug-in, this should return a uint32_t that can be understood by the Sound Engine part of
  118. * your sink plug-in. It must not return duplicates or pointers, and the value should be applicable to the
  119. * GetName call based on the same in_num.
  120. *
  121. * \param[in] in_this Current instance of this interface.
  122. * \param[in] in_num Device number, from zero to the value, as retrieved by GetCount.
  123. * \return uint32_t Device ID for the interface in_num.
  124. *
  125. * \sa \ref GetCount for a discussion on providing data in a multithread-aware environment.
  126. */
  127. uint32_t(*GetDeviceID)(const struct ak_wwise_plugin_sink_devices_instance_v1* in_this, int in_num);
  128. };
  129. #define AK_WWISE_PLUGIN_SINK_DEVICES_V1_ID() \
  130. AK_WWISE_PLUGIN_BASE_INTERFACE_FROM_ID(AK_WWISE_PLUGIN_INTERFACE_TYPE_SINK_DEVICES, 1)
  131. #define AK_WWISE_PLUGIN_SINK_DEVICES_V1_CTOR(/* ak_wwise_plugin_info* */ in_pluginInfo, /* void* */ in_data) \
  132. { \
  133. .m_baseInterface = AK_WWISE_PLUGIN_BASE_INTERFACE_CTOR(AK_WWISE_PLUGIN_SINK_DEVICES_V1_ID(), in_pluginInfo, in_data) \
  134. }
  135. #ifdef __cplusplus
  136. namespace AK::Wwise::Plugin
  137. {
  138. namespace V1
  139. {
  140. using CSinkDevices = ak_wwise_plugin_sink_devices_v1; ///< \copydoc ak_wwise_plugin_sink_devices_v1
  141. /**
  142. * \brief C++ API to provide device enumeration for sink plug-ins.
  143. *
  144. * Allows your plug-in to provide a list of up-to-date device IDs that can be used to instantiate a new Sound
  145. * Engine sink.
  146. *
  147. * This plug-in interface cannot be linked to a backend or a frontend plug-in, it must be standalone.
  148. *
  149. * \sa
  150. * - \ref ak_wwise_plugin_sink_devices_v1 C interface
  151. * - \ref AK_WWISE_PLUGIN_INTERFACE_TYPE_SINK_DEVICES
  152. */
  153. class SinkDevices : public CSinkDevices::Instance
  154. {
  155. public:
  156. /**
  157. * \copydoc CSinkDevices::Instance
  158. */
  159. using Instance = CSinkDevices::Instance;
  160. /**
  161. * \brief The interface type, as provided by this plug-in.
  162. */
  163. enum : InterfaceTypeValue
  164. {
  165. /**
  166. * \brief The interface type, as provided by this plug-in.
  167. */
  168. k_interfaceType = AK_WWISE_PLUGIN_INTERFACE_TYPE_SINK_DEVICES
  169. };
  170. /**
  171. * \brief The interface version, as provided by this plug-in.
  172. */
  173. enum : InterfaceVersion
  174. {
  175. /**
  176. * \brief The interface version, as provided by this plug-in.
  177. */
  178. k_interfaceVersion = 1
  179. };
  180. /**
  181. * \brief The C interface, fulfilled by your plug-in.
  182. */
  183. struct Interface : public CSinkDevices
  184. {
  185. using Instance = SinkDevices; ///< \copydoc SinkDevices
  186. Interface()
  187. {
  188. CSinkDevices::GetCount = [](const struct ak_wwise_plugin_sink_devices_instance_v1* in_this) { return static_cast<const Instance*>(in_this)->GetCount(); };
  189. CSinkDevices::GetName = [](const struct ak_wwise_plugin_sink_devices_instance_v1* in_this, int in_num) { return static_cast<const Instance*>(in_this)->GetName(in_num); };
  190. CSinkDevices::GetDeviceID = [](const struct ak_wwise_plugin_sink_devices_instance_v1* in_this, int in_num) { return static_cast<const Instance*>(in_this)->GetDeviceID(in_num); };
  191. }
  192. };
  193. /**
  194. * \internal
  195. * \brief Get the static Interface object, as used internally in AK::Wwise::Plugin::PluginInfoGenerator.
  196. */
  197. InterfacePtr GetInterfacePointer() {
  198. static Interface g_interface;
  199. return &g_interface;
  200. }
  201. /**
  202. * \internal
  203. * \brief Get the static Instance object, as used internally in AK::Wwise::Plugin::PluginInfoGenerator.
  204. */
  205. CSinkDevices::Instance* GetInstancePointer() {
  206. return this;
  207. }
  208. /**
  209. * \internal
  210. * \brief Get the static Instance object, as used internally in AK::Wwise::Plugin::PluginInfoGenerator.
  211. */
  212. const CSinkDevices::Instance* GetInstancePointer() const {
  213. return this;
  214. }
  215. SinkDevices() :
  216. CSinkDevices::Instance()
  217. {
  218. }
  219. virtual ~SinkDevices() {}
  220. /**
  221. * \brief Get a count of the number of interfaces currently available.
  222. *
  223. * Provided by your plug-in, this should return a count.
  224. *
  225. * \aknote
  226. * Due to the unpredictable nature of hardware configuration changes, an unpadded, basic system would return
  227. * a configuration that can change between a GetCount and subsequent objects retrieval.
  228. *
  229. * As a plug-in designer, you are responsible to address this by returning adequate values that make sense as a whole.
  230. *
  231. * To guide you, Sink Devices interface is used for retrieval and data copy in a tight loop over a single thread
  232. * at once. Host will retrieve the count, followed by the Name (GetName) and DeviceID (GetDeviceID), in the
  233. * order the compiler sees fit. Data is expected to survive for the amount of time this tight loop exists.
  234. *
  235. * \code
  236. * int count = m_interface->GetCount(m_instance);
  237. * for (int i = 0; i < count; ++i)
  238. * {
  239. * result.emplace_back(
  240. * m_interface->GetName(m_instance, i),
  241. * m_interface->GetDeviceID(m_instance, i)
  242. * );
  243. * }
  244. * \endcode
  245. *
  246. * A proposal is to use GetCount to internally retrieve the device names and IDs, make a static internal
  247. * cache, and then return name and device ID based on this cache.
  248. *
  249. * You can also spawn an event listener or an update thread, and ensure the data is up to date when the calls
  250. * come in, and block updates until all calls are accounted for.
  251. * \endaknote
  252. *
  253. * \return int Count of the number of interfaces available.
  254. */
  255. virtual int GetCount() const = 0;
  256. /**
  257. * \brief Get a user-presentable name for the device number in_num.
  258. *
  259. * Provided by your plug-in, this should return a const char* in UTF-8, valid at least until the next
  260. * function call, and must not return duplicates or nullptr.
  261. *
  262. * It should return names that can be understood by an end user in the context of your plug-in.
  263. *
  264. * \param[in] in_num Device number, from zero to the value, as retrieved by GetCount.
  265. * \return const char* UTF-8 Name of the interface in_num.
  266. *
  267. * \sa \ref GetCount for a discussion on providing data in a multithread-aware environment.
  268. */
  269. virtual const char* GetName(int in_num) const = 0;
  270. /**
  271. * \brief Get a device ID for the device number in_num.
  272. *
  273. * Provided by your plug-in, this should return a uint32_t that can be understood by the Sound Engine part of
  274. * your sink plug-in. It must not return duplicates or pointers, and the value should be applicable to the
  275. * GetName call based on the same in_num.
  276. *
  277. * \param[in] in_num Device number, from zero to the value, as retrieved by GetCount.
  278. * \return uint32_t Device ID for the interface in_num.
  279. *
  280. * \sa \ref GetCount for a discussion on providing data in a multithread-aware environment.
  281. */
  282. virtual uint32_t GetDeviceID(int in_num) const = 0;
  283. };
  284. } // of namespace V1
  285. /// Latest version of the C SinkDevices interface.
  286. using CSinkDevices = V1::CSinkDevices;
  287. /// Latest version of the C++ SinkDevices interface.
  288. using SinkDevices = V1::SinkDevices;
  289. AK_WWISE_PLUGIN_SPECIALIZE_INTERFACE_CLASS(SinkDevices);
  290. AK_WWISE_PLUGIN_SPECIALIZE_INTERFACE_VERSION(SinkDevices);
  291. } // of namespace AK::Wwise::Plugin
  292. #endif // of __cplusplus