IAkStreamMgr.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  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. /// \file
  21. /// Defines the API of Audiokinetic's I/O streaming solution.
  22. #ifndef _IAK_STREAM_MGR_H_
  23. #define _IAK_STREAM_MGR_H_
  24. #include <AK/SoundEngine/Common/AkMemoryMgr.h>
  25. //-----------------------------------------------------------------------------
  26. // Defines.
  27. //-----------------------------------------------------------------------------
  28. /// \name Profiling string lengths.
  29. //@{
  30. #define AK_MONITOR_STREAMNAME_MAXLENGTH (64)
  31. #define AK_MONITOR_DEVICENAME_MAXLENGTH (16)
  32. //@}
  33. //-----------------------------------------------------------------------------
  34. // Enums.
  35. //-----------------------------------------------------------------------------
  36. /// Stream status.
  37. enum AkStmStatus
  38. {
  39. AK_StmStatusIdle = 0, ///< The stream is idle
  40. AK_StmStatusCompleted = 1, ///< Operation completed / Automatic stream reached end
  41. AK_StmStatusPending = 2, ///< Operation pending / The stream is waiting for I/O
  42. AK_StmStatusCancelled = 3, ///< Operation cancelled
  43. AK_StmStatusError = 4 ///< The low-level I/O reported an error
  44. };
  45. /// Move method for position change.
  46. /// \sa
  47. /// - AK::IAkStdStream::SetPosition()
  48. /// - AK::IAkAutoStream::SetPosition()
  49. enum AkMoveMethod
  50. {
  51. AK_MoveBegin = 0, ///< Move offset from the start of the stream
  52. AK_MoveCurrent = 1, ///< Move offset from the current stream position
  53. AK_MoveEnd = 2 ///< Move offset from the end of the stream
  54. };
  55. /// File open mode.
  56. enum AkOpenMode
  57. {
  58. AK_OpenModeRead = 0, ///< Read-only access
  59. AK_OpenModeWrite = 1, ///< Write-only access (opens the file if it already exists)
  60. AK_OpenModeWriteOvrwr = 2, ///< Write-only access (deletes the file if it already exists)
  61. AK_OpenModeReadWrite = 3 ///< Read and write access
  62. };
  63. /// File system flags for file descriptors mapping.
  64. struct AkFileSystemFlags
  65. {
  66. AkFileSystemFlags()
  67. : uCacheID( AK_INVALID_FILE_ID ), uDirectoryHash( AK_INVALID_UNIQUE_ID ) {}
  68. AkFileSystemFlags( AkUInt32 in_uCompanyID, AkUInt32 in_uCodecID, AkUInt32 in_uCustomParamSize, void * in_pCustomParam, bool in_bIsLanguageSpecific, AkFileID in_uCacheID )
  69. : uCompanyID( in_uCompanyID )
  70. , uCodecID( in_uCodecID )
  71. , uCustomParamSize( in_uCustomParamSize )
  72. , pCustomParam( in_pCustomParam )
  73. , bIsLanguageSpecific( in_bIsLanguageSpecific )
  74. , uCacheID( in_uCacheID )
  75. , uNumBytesPrefetch( 0 )
  76. , uDirectoryHash( AK_INVALID_UNIQUE_ID ) {}
  77. AkUInt32 uCompanyID; ///< Company ID (Wwise uses AKCOMPANYID_AUDIOKINETIC, defined in AkTypes.h, for soundbanks and standard streaming files, and AKCOMPANYID_AUDIOKINETIC_EXTERNAL for streaming external sources).
  78. AkUInt32 uCodecID; ///< File/codec type ID (defined in AkTypes.h)
  79. AkUInt32 uCustomParamSize; ///< Size of the custom parameter
  80. void * pCustomParam; ///< Custom parameter
  81. bool bIsLanguageSpecific;///< True when the file location depends on language
  82. bool bIsAutomaticStream; ///< True when the file is opened to be used as an automatic stream. Note that you don't need to set it.
  83. ///< If you pass an AkFileSystemFlags to IAkStreamMgr CreateStd|Auto(), it will be set internally to the correct value.
  84. AkFileID uCacheID; ///< Cache ID for caching system used by automatic streams. The user is responsible for guaranteeing unicity of IDs.
  85. ///< When set, it supersedes the file ID passed to AK::IAkStreamMgr::CreateAuto() (ID version). Caching is optional and depends on the implementation.
  86. AkUInt32 uNumBytesPrefetch; ///< Indicates the number of bytes from the beginning of the file that should be streamed into cache via a caching stream. This field is only relevant when opening caching streams via
  87. ///< AK::IAkStreamMgr::PinFileInCache() and AK::SoundEngine::PinEventInStreamCache(). When using AK::SoundEngine::PinEventInStreamCache(),
  88. ///< it is initialized to the prefetch size stored in the sound bank, but may be changed by the file location resolver, or set to 0 to cancel caching.
  89. AkUInt32 uDirectoryHash; ///< If the implementation uses a hashed directory structure, this is the hash value that should be employed for determining the directory structure
  90. };
  91. /// Stream information.
  92. /// \sa
  93. /// - AK::IAkStdStream::GetInfo()
  94. /// - AK::IAkAutoStream::GetInfo()
  95. struct AkStreamInfo
  96. {
  97. AkDeviceID deviceID; ///< Device ID
  98. const AkOSChar * pszName; ///< User-defined stream name (specified through AK::IAkStdStream::SetStreamName() or AK::IAkAutoStream::SetStreamName())
  99. AkUInt64 uSize; ///< Total stream/file size in bytes
  100. bool bIsOpen; ///< True when the file is open (implementations may defer file opening)
  101. };
  102. /// Automatic streams heuristics.
  103. struct AkAutoStmHeuristics
  104. {
  105. AkReal32 fThroughput; ///< Average throughput in bytes/ms
  106. AkUInt32 uLoopStart; ///< Set to the start of loop (byte offset from the beginning of the stream) for streams that loop, 0 otherwise
  107. AkUInt32 uLoopEnd; ///< Set to the end of loop (byte offset from the beginning of the stream) for streams that loop, 0 otherwise
  108. AkUInt8 uMinNumBuffers; ///< Minimum number of buffers if you plan to own more than one buffer at a time, 0 or 1 otherwise
  109. ///< \remarks You should always release buffers as fast as possible, therefore this heuristic should be used only when
  110. ///< dealing with special contraints, like drivers or hardware that require more than one buffer at a time.\n
  111. ///< Also, this is only a heuristic: it does not guarantee that data will be ready when calling AK::IAkAutoStream::GetBuffer().
  112. AkPriority priority; ///< The stream priority. it should be between AK_MIN_PRIORITY and AK_MAX_PRIORITY (included).
  113. };
  114. /// Automatic streams buffer settings/constraints.
  115. struct AkAutoStmBufSettings
  116. {
  117. AkUInt32 uBufferSize; ///< Hard user constraint: When non-zero, forces the I/O buffer to be of size uBufferSize
  118. ///< (overriding the device's granularity).
  119. ///< Otherwise, the size is determined by the device's granularity.
  120. AkUInt32 uMinBufferSize; ///< Soft user constraint: When non-zero, specifies a minimum buffer size
  121. ///< \remarks Ignored if uBufferSize is specified.
  122. AkUInt32 uBlockSize; ///< Hard user constraint: When non-zero, buffer size will be a multiple of that number, and returned addresses will always be aligned on multiples of this value.
  123. };
  124. /// \name Profiling structures.
  125. //@{
  126. #pragma pack(push, 4)
  127. /// Device descriptor.
  128. struct AkDeviceDesc
  129. {
  130. AkDeviceID deviceID; ///< Device ID
  131. bool bCanWrite; ///< Specifies whether or not the device is writable
  132. bool bCanRead; ///< Specifies whether or not the device is readable
  133. AkUtf16 szDeviceName[AK_MONITOR_DEVICENAME_MAXLENGTH]; ///< Device name
  134. AkUInt32 uStringSize; ///< Device name string's size (number of characters)
  135. };
  136. /// Device descriptor.
  137. struct AkDeviceData
  138. {
  139. AkDeviceID deviceID; ///< Device ID
  140. AkUInt32 uMemSize; ///< IO memory pool size
  141. AkUInt32 uMemUsed; ///< IO memory pool used
  142. AkUInt32 uAllocs; ///< Cumulative number of allocations
  143. AkUInt32 uFrees; ///< Cumulative number of deallocations
  144. AkUInt32 uPeakRefdMemUsed; ///< Memory peak since monitoring started
  145. AkUInt32 uUnreferencedCachedBytes; ///< IO memory that is cached but is not currently used for active streams.
  146. AkUInt32 uGranularity; ///< IO memory pool block size
  147. AkUInt32 uNumActiveStreams; ///< Number of streams that have been active in the previous frame
  148. AkUInt32 uTotalBytesTransferred; ///< Number of bytes transferred, including cached transfers
  149. AkUInt32 uLowLevelBytesTransferred; ///< Number of bytes transferred exclusively via low-level
  150. AkReal32 fAvgCacheEfficiency; ///< Total bytes from cache as a percentage of total bytes.
  151. AkUInt32 uNumLowLevelRequestsCompleted; ///< Number of low-level transfers that have completed in the previous monitoring frame
  152. AkUInt32 uNumLowLevelRequestsCancelled; ///< Number of low-level transfers that were cancelled in the previous monitoring frame
  153. AkUInt32 uNumLowLevelRequestsPending; ///< Number of low-level transfers that are currently pending
  154. AkUInt32 uCustomParam; ///< Custom number queried from low-level IO.
  155. AkUInt32 uCachePinnedBytes; ///< Number of bytes that can be pinned into cache.
  156. };
  157. /// Stream general information.
  158. struct AkStreamRecord
  159. {
  160. AkUInt32 uStreamID; ///< Unique stream identifier
  161. AkDeviceID deviceID; ///< Device ID
  162. AkUtf16 szStreamName[AK_MONITOR_STREAMNAME_MAXLENGTH]; ///< Stream name
  163. AkUInt32 uStringSize; ///< Stream name string's size (number of characters)
  164. AkUInt64 uFileSize; ///< File size
  165. AkUInt32 uCustomParamSize; ///< File descriptor's uCustomParamSize
  166. AkUInt32 uCustomParam; ///< File descriptor's pCustomParam (on 32 bits)
  167. bool bIsAutoStream; ///< True for auto streams
  168. bool bIsCachingStream; ///< True for caching streams
  169. };
  170. /// Stream statistics.
  171. struct AkStreamData
  172. {
  173. AkUInt32 uStreamID; ///< Unique stream identifier
  174. // Status (replace)
  175. AkUInt32 uPriority; ///< Stream priority
  176. AkUInt64 uFilePosition; ///< Current position
  177. AkUInt32 uTargetBufferingSize; ///< Total stream buffer size (specific to IAkAutoStream)
  178. AkUInt32 uVirtualBufferingSize; ///< Size of available data including requested data (specific to IAkAutoStream)
  179. AkUInt32 uBufferedSize; ///< Size of available data (specific to IAkAutoStream)
  180. AkUInt32 uNumBytesTransfered; ///< Transfered amount since last query (Accumulate/Reset)
  181. AkUInt32 uNumBytesTransferedLowLevel;///< Transfered amount (from low-level IO only) since last query (Accumulate/Reset)
  182. AkUInt32 uMemoryReferenced; ///< Amount of streaming memory referenced by this stream
  183. AkReal32 fEstimatedThroughput; ///< Estimated throughput heuristic
  184. bool bActive; ///< True if this stream has been active (that is, was ready for I/O or had at least one pending I/O transfer, uncached or not) in the previous frame
  185. };
  186. #pragma pack(pop)
  187. //@}
  188. namespace AK
  189. {
  190. /// \name Profiling interfaces.
  191. //@{
  192. /// Profiling interface of streams.
  193. /// \akwarning
  194. /// The functions in this interface are not thread-safe, unless stated otherwise.
  195. /// \endakwarning
  196. class IAkStreamProfile
  197. {
  198. protected:
  199. /// Virtual destructor on interface to avoid warnings.
  200. virtual ~IAkStreamProfile(){}
  201. public:
  202. /// Returns the stream's record (once).
  203. /// \sa
  204. /// - \ref streamingdevicemanager
  205. virtual void GetStreamRecord(
  206. AkStreamRecord & out_streamRecord ///< Returned stream record interface
  207. ) = 0;
  208. /// Returns the stream's statistics (every profile frame).
  209. /// \sa
  210. /// - \ref streamingdevicemanager
  211. virtual void GetStreamData(
  212. AkStreamData & out_streamData ///< Returned periodic stream data interface
  213. ) = 0;
  214. /// Query the stream's "new" flag.
  215. /// \return True, until AK::IAkStreamProfile::ClearNew() is called.
  216. /// \sa
  217. /// - \ref streamingdevicemanager
  218. virtual bool IsNew() = 0;
  219. /// Resets the stream's "new" flag.
  220. /// \sa
  221. /// - \ref streamingdevicemanager
  222. virtual void ClearNew() = 0;
  223. };
  224. /// Profiling interface of high-level I/O devices.
  225. /// \akwarning
  226. /// The functions in this interface are not thread-safe, unless stated otherwise.
  227. /// \endakwarning
  228. class IAkDeviceProfile
  229. {
  230. protected:
  231. /// Virtual destructor on interface to avoid warnings.
  232. virtual ~IAkDeviceProfile(){}
  233. public:
  234. /// Notify device when monitor sampling starts.
  235. virtual void OnProfileStart() = 0;
  236. /// Notify device when monitor sampling ends.
  237. virtual void OnProfileEnd() = 0;
  238. /// Query the device's description (once).
  239. /// \sa
  240. /// - \ref streamingdevicemanager
  241. virtual void GetDesc(
  242. AkDeviceDesc & out_deviceDesc ///< Device descriptor.
  243. ) = 0;
  244. /// Query the device's statistics (at every profiling frame).
  245. /// \sa
  246. /// - \ref streamingdevicemanager
  247. virtual void GetData(
  248. AkDeviceData & out_deviceData ///< Device data.
  249. ) = 0;
  250. /// Query the device's "new" flag.
  251. /// \return True, until ClearNew() is called.
  252. /// \sa
  253. /// - \ref streamingdevicemanager
  254. virtual bool IsNew() = 0;
  255. /// Resets the device's "new" flag.
  256. /// \sa
  257. /// - \ref streamingdevicemanager
  258. virtual void ClearNew() = 0;
  259. /// Get the number of streams currently associated with that device.
  260. /// \return The number of streams
  261. /// \sa
  262. /// - \ref streamingdevicemanager
  263. virtual AkUInt32 GetNumStreams() = 0;
  264. /// Get a stream profile, for a specified stream index.
  265. /// \remarks GetStreamProfile() refers to streams by index, which must honor the call to AK::IAkDeviceProfile::GetNumStreams().
  266. /// \sa
  267. /// - \ref streamingdevicemanager
  268. virtual IAkStreamProfile * GetStreamProfile(
  269. AkUInt32 in_uStreamIndex ///< Stream index: [0,numStreams[
  270. ) = 0;
  271. };
  272. /// Profiling interface of the Stream Manager.
  273. /// \akwarning
  274. /// The functions in this interface are not thread-safe, unless stated otherwise.
  275. /// \endakwarning
  276. class IAkStreamMgrProfile
  277. {
  278. protected:
  279. /// Virtual destructor on interface to avoid warnings.
  280. virtual ~IAkStreamMgrProfile(){}
  281. public:
  282. /// Start profile monitoring.
  283. /// \return AK_Success if successful, AK_Fail otherwise.
  284. /// \sa
  285. /// - \ref streamingdevicemanager
  286. virtual AKRESULT StartMonitoring() = 0;
  287. /// Stop profile monitoring.
  288. /// \sa
  289. /// - \ref streamingdevicemanager
  290. virtual void StopMonitoring() = 0;
  291. /// Device enumeration.
  292. /// \return The number of devices.
  293. /// \sa
  294. /// - \ref streamingdevicemanager
  295. virtual AkUInt32 GetNumDevices() = 0;
  296. /// Get a device profile for a specified device index.
  297. /// \remarks GetDeviceProfile() refers to devices by index, which must honor the call to AK::IAkStreamMgrProfile::GetNumDevices().
  298. /// \remarks The device index is not the same as the device ID (AkDeviceID).
  299. /// \sa
  300. /// - \ref streamingdevicemanager
  301. virtual IAkDeviceProfile * GetDeviceProfile(
  302. AkUInt32 in_uDeviceIndex ///< Device index: [0,numDevices[
  303. ) = 0;
  304. };
  305. //@}
  306. /// \name High-level streams API.
  307. //@{
  308. /// Interface of standard streams. Used as a handle to a standard stream. Has methods for
  309. /// stream control. Obtained through the Stream Manager's AK::IAkStreamMgr::CreateStd() method.
  310. /// \akwarning
  311. /// The functions in this interface are not thread-safe, unless stated otherwise.
  312. /// \endakwarning
  313. class IAkStdStream
  314. {
  315. protected:
  316. /// Virtual destructor on interface to avoid warnings.
  317. virtual ~IAkStdStream(){}
  318. public:
  319. /// \name Stream management and settings.
  320. //@{
  321. /// Close the stream. The object is destroyed and the interface becomes invalid.
  322. /// \sa
  323. /// - \ref streamingdevicemanager
  324. virtual void Destroy() = 0;
  325. /// Get information about a stream.
  326. /// \sa
  327. /// - \ref streamingdevicemanager
  328. virtual void GetInfo(
  329. AkStreamInfo & out_info ///< Returned stream info
  330. ) = 0;
  331. /// Returns a unique cookie for a given stream.
  332. /// The default implementation of the Stream Manager returns its file descriptor (see AkStreamMgrModule.h).
  333. virtual void * GetFileDescriptor() = 0;
  334. /// Give the stream a name (appears in the Wwise Profiler).
  335. /// \sa
  336. /// - \ref streamingdevicemanager
  337. virtual AKRESULT SetStreamName(
  338. const AkOSChar * in_pszStreamName ///< Stream name
  339. ) = 0;
  340. /// Get the I/O block size.
  341. /// \remark Queries the low-level I/O, by calling AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize() with the
  342. /// stream's file descriptor.
  343. /// \return The block size, in bytes.
  344. /// \sa
  345. /// - \ref streamingdevicemanager
  346. virtual AkUInt32 GetBlockSize() = 0;
  347. //@}
  348. /// \name I/O operations.
  349. //@{
  350. /// Schedule a read request.
  351. /// \warning Use only with a multiple of the block size, queried via AK::IAkStdStream::GetBlockSize().
  352. /// \remarks If the call is asynchronous (in_bWait = false), wait until AK::IAkStdStream::GetStatus() stops returning AK_StmStatusPending.
  353. /// \return AK_Success if the operation was successfully scheduled (but not necessarily completed)
  354. /// \sa
  355. /// - \ref streamingdevicemanager
  356. virtual AKRESULT Read(
  357. void * in_pBuffer, ///< User buffer address
  358. AkUInt32 in_uReqSize, ///< Requested read size
  359. bool in_bWait, ///< Block until the operation is complete
  360. AkPriority in_priority, ///< Heuristic: operation priority
  361. AkReal32 in_fDeadline, ///< Heuristic: operation deadline (ms)
  362. AkUInt32 & out_uSize ///< The size that was actually read
  363. ) = 0;
  364. /// Schedule a write request.
  365. /// \warning Use only with a multiple of the block size, queried via AK::IAkStdStream::GetBlockSize().
  366. /// \remarks If the call is asynchronous (in_bWait = false), wait until GetStatus() stops returning AK_StmStatusPending.
  367. /// \return AK_Success if the operation was successfully scheduled
  368. /// \sa
  369. /// - \ref streamingdevicemanager
  370. virtual AKRESULT Write(
  371. void * in_pBuffer, ///< User buffer address
  372. AkUInt32 in_uReqSize, ///< Requested write size
  373. bool in_bWait, ///< Block until the operation is complete
  374. AkPriority in_priority, ///< Heuristic: operation priority
  375. AkReal32 in_fDeadline, ///< Heuristic: operation deadline (ms)
  376. AkUInt32 & out_uSize ///< The size that was actually written
  377. ) = 0;
  378. /// Get the current stream position.
  379. /// \remarks If an operation is pending, there is no guarantee that the position was queried before (or after) the operation was completed.
  380. /// \return The current stream position
  381. /// \sa
  382. /// - \ref streamingdevicemanager
  383. virtual AkUInt64 GetPosition(
  384. bool * out_pbEndOfStream ///< Returned end-of-stream flag, only for streams opened with AK_OpenModeRead (can pass NULL)
  385. ) = 0;
  386. /// Set the stream position. Modifies the position for the next read/write operation.
  387. /// \warning No operation should be pending.
  388. /// \remarks The new position will snap to the lowest block boundary.
  389. /// \return AK_Success if the stream position was changed
  390. /// \sa
  391. /// - \ref streamingdevicemanager
  392. virtual AKRESULT SetPosition(
  393. AkInt64 in_iMoveOffset, ///< Seek offset
  394. AkMoveMethod in_eMoveMethod, ///< Seek method, from the beginning, end, or current file position
  395. AkInt64 * out_piRealOffset ///< The actual seek offset may differ from the expected value when the block size is bigger than 1.
  396. ///< In that case, the seek offset floors to the sector boundary. Can pass NULL.
  397. ) = 0;
  398. /// Cancel the current operation.
  399. /// \remarks When it returns, the caller is guaranteed that no operation is pending.
  400. /// \remarks This method can block the caller for the whole duration of the I/O operation, if the request was already posted.
  401. /// \sa
  402. /// - \ref streamingdevicemanager
  403. virtual void Cancel() = 0;
  404. //@}
  405. /// \name Access to data and status.
  406. //@{
  407. /// Get user data (and accessed size).
  408. /// \return The address of data provided by user
  409. /// \sa
  410. /// - \ref streamingdevicemanager
  411. virtual void * GetData(
  412. AkUInt32 & out_uSize ///< Size actually read or written
  413. ) = 0;
  414. /// Get the stream's status.
  415. /// \return The stream status.
  416. /// \sa
  417. /// - \ref streamingdevicemanager
  418. virtual AkStmStatus GetStatus() = 0;
  419. /// Block and wait for a pending read to finish, and return the current status of the stream.
  420. /// This will return immediately if the status is not pending.
  421. /// \return The stream status.
  422. /// \sa
  423. /// - \ref streamingdevicemanager
  424. virtual AkStmStatus WaitForPendingOperation() = 0;
  425. //@}
  426. };
  427. /// Interface of automatic streams. It is used as a handle to a stream,
  428. /// I/O operations are triggered from here.
  429. /// Obtained through the Stream Manager's AK::IAkStreamMgr::CreateAuto() method.
  430. /// \akwarning
  431. /// The functions in this interface are not thread-safe, unless stated otherwise.
  432. /// \endakwarning
  433. /// \sa
  434. /// - \ref streamingdevicemanager
  435. class IAkAutoStream
  436. {
  437. protected:
  438. /// Virtual destructor on interface to avoid warnings.
  439. virtual ~IAkAutoStream(){}
  440. public:
  441. /// \name Stream management, settings access, and run-time change.
  442. //@{
  443. /// Close the stream. The object is destroyed and the interface becomes invalid.
  444. /// \sa
  445. /// - \ref streamingdevicemanager
  446. virtual void Destroy() = 0;
  447. /// Get information about the stream.
  448. /// \sa
  449. /// - \ref streamingdevicemanager
  450. virtual void GetInfo(
  451. AkStreamInfo & out_info ///< Returned stream info
  452. ) = 0;
  453. /// Returns a unique cookie for a given stream.
  454. /// The default implementation of the Stream Manager returns its file descriptor (see AkStreamMgrModule.h).
  455. virtual void * GetFileDescriptor() = 0;
  456. /// Get the stream's heuristics.
  457. /// \sa
  458. /// - \ref streamingdevicemanager
  459. virtual void GetHeuristics(
  460. AkAutoStmHeuristics & out_heuristics///< Returned stream heuristics
  461. ) = 0;
  462. /// Run-time change of the stream's heuristics.
  463. /// \sa
  464. /// - \ref streamingdevicemanager
  465. virtual AKRESULT SetHeuristics(
  466. const AkAutoStmHeuristics & in_heuristics ///< New stream heuristics
  467. ) = 0;
  468. /// Run-time change of the stream's minimum buffer size that can be handed out to client
  469. /// in GetBuffer() (except the last buffer at the end of file).
  470. /// Corresponds to the uMinBufferSize field of the AkAutoStmBufSettings passed to CreateAuto().
  471. /// \sa
  472. /// - AkAutoStmBufSettings
  473. /// - \ref streamingdevicemanager
  474. virtual AKRESULT SetMinimalBufferSize(
  475. AkUInt32 in_uMinBufferSize ///< Minimum buffer size that can be handed out to client.
  476. ) = 0;
  477. /// Set the minimum size to buffer ahead in an automated stream.
  478. ///
  479. /// This function was made available to allow systems that cannot only rely on AkAutoStmHeuristics::fThroughput to predict what will be the best target size of an automatic stream.
  480. /// The system will predict the minimum size to buffer and will consider this value as the minimal size to be the target.
  481. /// \sa
  482. /// - AkAutoStmBufSettings
  483. /// - \ref streamingdevicemanager
  484. /// - \ref AkAutoStmHeuristics
  485. virtual AKRESULT SetMinTargetBufferSize(
  486. AkUInt32 in_uMinTargetBufferSize ///< Minimum size to buffer ahead in an automated stream. (in bytes)
  487. ) = 0;
  488. /// Give the stream a name (appears in the Wwise profiler).
  489. /// \sa
  490. /// - \ref streamingdevicemanager
  491. virtual AKRESULT SetStreamName(
  492. const AkOSChar * in_pszStreamName ///< Stream name
  493. ) = 0;
  494. /// Get the I/O block size.
  495. /// \remark Queries the actual low-level I/O device, by calling AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize() with the
  496. /// stream's file descriptor.
  497. /// \return The block size (in bytes)
  498. /// \sa
  499. /// - \ref streamingdevicemanager
  500. virtual AkUInt32 GetBlockSize() = 0;
  501. /// Get the amount of buffering that the stream has.
  502. /// The buffering is defined as the number of bytes that the stream has buffered, excluding the number
  503. /// of bytes that is currently granted to the user (with GetBuffer()).
  504. /// \remark The returned value corresponds to the buffering status at that moment, and does not even
  505. /// guarantee that it will not shrink.
  506. /// \return
  507. /// - AK_DataReady: Some data has been buffered (out_uNumBytesAvailable is greater than 0).
  508. /// - AK_NoDataReady: No data is available, and the end of file has not been reached.
  509. /// - AK_NoMoreData: Some or no data is available, but the end of file has been reached. The stream will not buffer any more data.
  510. /// - AK_Fail: The stream is invalid due to an I/O error.
  511. virtual AKRESULT QueryBufferingStatus(
  512. AkUInt32 & out_uNumBytesAvailable ///< Number of bytes available in the stream's buffer(s).
  513. ) = 0;
  514. /// Returns the target buffering size based on the throughput heuristic.
  515. /// \return
  516. /// Target buffering length expressed in bytes.
  517. virtual AkUInt32 GetNominalBuffering() = 0;
  518. //@}
  519. /// \name Stream operations.
  520. //@{
  521. /// Start the automatic scheduling.
  522. /// \return AK_Success if the automatic scheduling was started successfully
  523. /// \sa
  524. /// - \ref streamingdevicemanager
  525. virtual AKRESULT Start() = 0;
  526. /// Stop the automatic scheduling.
  527. /// \return AK_Success if the automatic scheduling was stopped successfully.
  528. /// \sa
  529. /// - \ref streamingdevicemanager
  530. virtual AKRESULT Stop() = 0;
  531. /// Get the stream's position.
  532. /// \remarks The stream position is the position seen by the user, not the position of the file
  533. /// already streamed into the Stream Manager's memory. The stream position is updated when buffers
  534. /// are released, using AK::IAkAutoStream::ReleaseBuffer().
  535. /// \return The file position in bytes of the beginning of the first buffer owned by the user.
  536. /// If the user does not own a buffer, it returns the position of the beginning of the buffer that
  537. /// would be returned from a call to AK::IAkAutoStream::GetBuffer().
  538. /// \sa
  539. /// - \ref streamingdevicemanager
  540. virtual AkUInt64 GetPosition(
  541. bool * out_pbEndOfStream ///< Returned end-of-stream flag (can pass NULL)
  542. ) = 0;
  543. /// Set the stream's position.
  544. /// The next call to AK::IAkAutoStream::GetBuffer() will grant data that corresponds to the position specified here.
  545. /// \remarks Data already streamed into the Stream Manager's memory might be flushed.
  546. /// \remarks The new position will round down to the low-level I/O block size.
  547. /// \return AK_Success if the resulting position is valid
  548. /// \sa
  549. /// - \ref streamingdevicemanager
  550. virtual AKRESULT SetPosition(
  551. AkInt64 in_iMoveOffset, ///< Seek offset
  552. AkMoveMethod in_eMoveMethod, ///< Seek method, from the beginning, end or current file position
  553. AkInt64 * out_piRealOffset ///< The actual seek offset may differ from the expected value when the low-level's block size is greater than 1.
  554. ///< In that case, the real absolute position rounds down to the block boundary. Can pass NULL.
  555. ) = 0;
  556. //@}
  557. /// \name Data/status access.
  558. //@{
  559. /// Get data from the Stream Manager buffers.
  560. /// \remarks Grants a buffer if data is available. Each successful call to this method returns a new
  561. /// buffer of data, at the current stream position.
  562. /// Buffers should be released as soon as they are not needed, using AK::IAkAutoStream::ReleaseBuffer().
  563. /// \aknote AK::IAkAutoStream::ReleaseBuffer() does not take any argument, because it releases buffers in order. \endaknote
  564. /// \return
  565. /// - AK_DataReady : the buffer was granted
  566. /// - AK_NoDataReady : the buffer is not granted yet (never happens when called with in_bWait flag)
  567. /// - AK_NoMoreData : the buffer was granted but reached end of file (next call will return with size 0)
  568. /// - AK_Fail : there was an I/O error
  569. /// \sa
  570. /// - \ref streamingdevicemanager
  571. virtual AKRESULT GetBuffer(
  572. void *& out_pBuffer, ///< Returned address of granted data space
  573. AkUInt32 & out_uSize, ///< Returned size of granted data space
  574. bool in_bWait ///< Block until data is ready
  575. ) = 0;
  576. /// Release buffer granted through GetBuffer(). Buffers are released in order.
  577. /// \return AK_Success if a valid buffer was released, AK_Fail if the user did not own any buffer.
  578. /// \note To implementers: Clients like the sound engine may release buffers until this function returns AK_Fail.
  579. /// Failing to release a buffer should not be considered as a fatal error.
  580. /// \sa
  581. /// - \ref streamingdevicemanager
  582. virtual AKRESULT ReleaseBuffer() = 0;
  583. //@}
  584. };
  585. //@}
  586. /// Interface of the Stream Manager.
  587. /// \akwarning
  588. /// The functions in this interface are not thread-safe, unless stated otherwise.
  589. /// \endakwarning
  590. class IAkStreamMgr
  591. {
  592. protected:
  593. /// Virtual destructor on interface to avoid warnings.
  594. virtual ~IAkStreamMgr(){}
  595. public:
  596. /// Global access to singleton.
  597. /// \return The interface of the global Stream Manager
  598. /// \sa
  599. /// - \ref streamingdevicemanager
  600. inline static IAkStreamMgr * Get()
  601. {
  602. return m_pStreamMgr;
  603. }
  604. /// Destroy the Stream Manager.
  605. /// \sa
  606. /// - \ref streamingdevicemanager
  607. virtual void Destroy() = 0;
  608. /// \name Profiling.
  609. //@{
  610. /// Get the profiling interface.
  611. /// \return The interface of the Stream Manager profiler
  612. virtual IAkStreamMgrProfile * GetStreamMgrProfile() = 0;
  613. //@}
  614. /// \name Stream creation interface.
  615. //@{
  616. // Standard stream creation methods.
  617. /// Create a standard stream (string overload).
  618. /// \return AK_Success if the stream was created successfully
  619. /// \remarks The string overload of AK::StreamMgr::IAkFileLocationResolver::Open() will be called.
  620. /// \sa
  621. /// - \ref streamingdevicemanager
  622. virtual AKRESULT CreateStd(
  623. const AkOSChar* in_pszFileName, ///< Application-defined string (title only, or full path, or code...)
  624. AkFileSystemFlags * in_pFSFlags, ///< Special file system flags. Can pass NULL
  625. AkOpenMode in_eOpenMode, ///< Open mode (read, write, ...)
  626. IAkStdStream *& out_pStream, ///< Returned interface to a standard stream. If the function does not return AK_Success, this pointer is left untouched.
  627. bool in_bSyncOpen ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion.
  628. ) = 0;
  629. /// Create a standard stream (ID overload).
  630. /// \return AK_Success if the stream was created successfully
  631. /// \remarks The ID overload of AK::StreamMgr::IAkFileLocationResolver::Open() will be called.
  632. /// \sa
  633. /// - \ref streamingdevicemanager
  634. virtual AKRESULT CreateStd(
  635. AkFileID in_fileID, ///< Application-defined ID
  636. AkFileSystemFlags * in_pFSFlags, ///< Special file system flags (can pass NULL)
  637. AkOpenMode in_eOpenMode, ///< Open mode (read, write, ...)
  638. IAkStdStream *& out_pStream, ///< Returned interface to a standard stream. If the function does not return AK_Success, this pointer is left untouched.
  639. bool in_bSyncOpen ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion.
  640. ) = 0;
  641. // Automatic stream create methods.
  642. /// Create an automatic stream (string overload).
  643. /// \return AK_Success if the stream was created successfully
  644. /// \remarks The stream needs to be started explicitly with AK::IAkAutoStream::Start().
  645. /// \remarks The string overload of AK::StreamMgr::IAkFileLocationResolver::Open() will be called.
  646. /// \sa
  647. /// - \ref streamingdevicemanager
  648. virtual AKRESULT CreateAuto(
  649. const AkOSChar* in_pszFileName, ///< Application-defined string (title only, or full path, or code...)
  650. AkFileSystemFlags * in_pFSFlags, ///< Special file system flags (can pass NULL)
  651. const AkAutoStmHeuristics & in_heuristics, ///< Streaming heuristics
  652. AkAutoStmBufSettings * in_pBufferSettings, ///< Stream buffer settings (it is recommended to pass NULL in order to use the default settings)
  653. IAkAutoStream *& out_pStream, ///< Returned interface to an automatic stream. If the function does not return AK_Success, this pointer is left untouched.
  654. bool in_bSyncOpen ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion.
  655. ) = 0;
  656. /// Create an automatic stream (ID overload).
  657. /// \return AK_Success if the stream was created successfully
  658. /// \remarks The stream needs to be started explicitly with IAkAutoStream::Start().
  659. /// \remarks The ID overload of AK::StreamMgr::IAkFileLocationResolver::Open() will be called.
  660. /// \sa
  661. /// - \ref streamingdevicemanager
  662. virtual AKRESULT CreateAuto(
  663. AkFileID in_fileID, ///< Application-defined ID
  664. AkFileSystemFlags * in_pFSFlags, ///< Special file system flags (can pass NULL)
  665. const AkAutoStmHeuristics & in_heuristics, ///< Streaming heuristics
  666. AkAutoStmBufSettings * in_pBufferSettings, ///< Stream buffer settings (it is recommended to pass NULL to use the default settings)
  667. IAkAutoStream *& out_pStream, ///< Returned interface to an automatic stream. If the function does not return AK_Success, this pointer is left untouched.
  668. bool in_bSyncOpen ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion.
  669. ) = 0;
  670. /// Create an automatic stream (in-memory buffer overload).
  671. ///
  672. /// This overload differs largely from CreateAuto() implementations, which are file based.
  673. /// This version is provided with a memory space and the resulting automatic stream will simply
  674. /// return the memory space in a similar fashion, but without the need to perform any actual file operations.
  675. ///
  676. /// If you are in the process of implementing your own IAkStreamMgr object,
  677. /// consider using the initial implementation from `\\SDK\\source\\StreamManager\\Common\\AkStreamMgr.cpp`.
  678. ///
  679. /// \return AK_Success if the stream was created successfully
  680. /// \remarks The stream needs to be started explicitly with IAkAutoStream::Start().
  681. /// \sa
  682. /// - \ref streamingdevicemanager
  683. virtual AKRESULT CreateAuto(
  684. void * in_pBuffer, ///< Pointer to the memory area containing stream data
  685. AkUInt64 in_uSize, ///< Size of the memory area containing stream data
  686. const AkAutoStmHeuristics & in_heuristics, ///< Streaming heuristics
  687. IAkAutoStream *& out_pStream ///< Returned interface to an automatic stream. If the function does not return AK_Success, this pointer is left untouched.
  688. ) = 0;
  689. /// Start streaming the first "in_pFSFlags->uNumBytesPrefetch" bytes of the file with id "in_fileID" into cache. The stream will be scheduled only after
  690. /// all regular streams (not file caching streams) are serviced. The file will stay cached until either the UnpinFileInCache is called,
  691. /// or the limit as set by uMaxCachePinnedBytes is reached and another higher priority file (in_uPriority) needs the space.
  692. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API.
  693. /// Using PinFileInCache() directly does not allow users to take advantage of sound bank data. The file and the number of bytes they wish to cache must be explicitly specified.
  694. ///
  695. /// \sa
  696. /// - \ref streamingdevicemanager
  697. /// - AK::SoundEngine::PinEventInStreamCache
  698. /// - AK::SoundEngine::UnpinEventInStreamCache
  699. /// - AkFileSystemFlags
  700. virtual AKRESULT PinFileInCache(
  701. AkFileID in_fileID, ///< Application-defined ID
  702. AkFileSystemFlags * in_pFSFlags, ///< Special file system flags (can NOT pass NULL)
  703. AkPriority in_uPriority ///< Stream caching priority. Note: Caching requests only get serviced after all regular streaming requests.
  704. ) = 0;
  705. /// Un-pin a file that has been previouly pinned into cache. This function must be called once for every call to PinFileInCache() with the same file id.
  706. /// The file may still remain in stream cache after this is called, until the memory is reused by the streaming memory manager in accordance with to its
  707. /// cache management algorithm.
  708. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API.
  709. /// Using UnpinFileInCache() directly does not allow users to take advantage of sound bank data. The file must be explicitly specified.
  710. /// \sa
  711. /// - \ref streamingdevicemanager
  712. /// - AK::SoundEngine::PinEventInStreamCache
  713. /// - AK::SoundEngine::UnpinEventInStreamCache
  714. virtual AKRESULT UnpinFileInCache(
  715. AkFileID in_fileID, ///< Application-defined ID
  716. AkPriority in_uPriority ///< Priority of stream that you are unpinning
  717. ) = 0;
  718. /// Update the priority of the caching stream. Higher priority streams will be serviced before lower priority caching streams, and will be more likely to stay in
  719. /// memory if the cache pin limit as set by "uMaxCachePinnedBytes" is reached.
  720. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API.
  721. /// Using UpdateCachingPriority() directly does not allow users to take advantage of sound bank data. The file must be explicitly specified.
  722. /// \sa
  723. /// - \ref streamingdevicemanager
  724. /// - AK::SoundEngine::PinEventInStreamCache
  725. /// - AK::SoundEngine::UnpinEventInStreamCache
  726. virtual AKRESULT UpdateCachingPriority(
  727. AkFileID in_fileID, ///< Application-defined ID
  728. AkPriority in_uPriority, ///< Priority
  729. AkPriority in_uOldPriority ///< Old priority
  730. ) = 0;
  731. /// Return information about a file that has been pinned into cache.
  732. /// Retrieves the percentage of the requested buffer size that has been streamed in and stored into stream cache, and whether
  733. /// the cache pinned memory limit is preventing this buffer from filling.
  734. virtual AKRESULT GetBufferStatusForPinnedFile(
  735. AkFileID in_fileID, ///< Application-defined ID
  736. AkReal32& out_fPercentBuffered, ///< Percentage of buffer full (out of 100)
  737. bool& out_bCacheFull ///< Set to true if the rest of the buffer can not fit into the cache-pinned memory limit.
  738. ) = 0;
  739. /// Make a memory stream point to a new area in memory, otherwise keeping the exact same state.
  740. virtual AKRESULT RelocateMemoryStream(
  741. IAkAutoStream * in_pStream, ///< The stream to relocate. Must be a stream created with the memory overload of CreateAutoStm.
  742. AkUInt8 * in_pNewStart ///< The new area in memory to point to
  743. ) = 0;
  744. //@}
  745. protected:
  746. /// Definition of the global pointer to the interface of the Stream Manager singleton.
  747. /// \sa
  748. /// - \ref streamingdevicemanager
  749. static AKSOUNDENGINE_API IAkStreamMgr * m_pStreamMgr;
  750. };
  751. }
  752. #endif //_IAK_STREAM_MGR_H_