IAkStreamMgr.h 41 KB

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