Version
menu_open
link
Wwise SDK 2019.1.11
AkStreamMgrModule.h
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 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Version: <VERSION> Build: <BUILDNUMBER>
25  Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
26 *******************************************************************************/
27 
28 /// \file
29 /// Audiokinetic's implementation-specific definitions and factory of
30 /// overridable Stream Manager module.
31 /// Contains the default Stream Manager's implementation-specific interfaces that altogether constitute
32 /// the Low-Level I/O submodule. This submodule needs to be implemented by the game. All I/O requests
33 /// generated by the Stream Manager end up to one of the I/O hooks defined herein.
34 /// Read \ref streamingmanager_lowlevel to learn more about the Low-Level I/O.
35 
36 #ifndef _AK_STREAM_MGR_MODULE_H_
37 #define _AK_STREAM_MGR_MODULE_H_
38 
39 #include <AK/SoundEngine/Common/IAkStreamMgr.h>
40 #include <AK/Tools/Common/AkPlatformFuncs.h>
41 
42 class CAkFilePackage;
43 
44 /// \name Audiokinetic Stream Manager's implementation-specific definitions.
45 //@{
46 /// Stream Manager initialization settings.
47 /// \sa
48 /// - AK::IAkStreamMgr
49 /// - AK::StreamMgr::Create()
50 /// - \ref streamingmanager_settings
51 
53 {
54  AkUInt32 uMemorySize; ///< Size of memory pool for small objects of Stream Manager.
55  ///< Small objects are the Stream Manager instance, devices,
56  ///< stream objects, user stream names, pending transfers,
57  ///< buffer records, pending open commands, and so on.
58  ///< Ideally, this pool should never run out of memory,
59  ///< because it may cause undesired I/O transfer
60  ///< cancellation, and even major CPU spikes. I/O memory should
61  ///< be bound by the size of each device's I/O pool instead.
62 };
63 
64 /// High-level IO devices initialization settings.
65 /// \sa
66 /// - AK::IAkStreamMgr
67 /// - AK::StreamMgr::CreateDevice()
68 /// - \ref streamingmanager_settings
70 {
71  void * pIOMemory; ///< Pointer for I/O memory allocated by user. This is fed directly to AK::MemoryMgr::CreatePool().
72  ///< Pass NULL if you want memory to be allocated by the MemoryMgr via AK alloc hooks.
73  ///< If specified, uIOMemorySize, uIOMemoryAlignment and ePoolAttributes are ignored.
74  AkUInt32 uIOMemorySize; ///< Size of memory pool for I/O (for automatic streams). It is passed directly to AK::MemoryMgr::CreatePool(), after having been rounded down to a multiple of uGranularity.
75  AkUInt32 uIOMemoryAlignment; ///< I/O memory pool alignment. It is passed directly to AK::MemoryMgr::CreatePool().
76  AkMemPoolAttributes ePoolAttributes; ///< Attributes for internal I/O memory pool. Note that these pools are always allocated internally as AkFixedSizeBlocksMode-style pools. Here, specify the block allocation type (AkMalloc, and so on). It is passed directly to AK::MemoryMgr::CreatePool().
77  AkUInt32 uGranularity; ///< I/O requests granularity (typical bytes/request).
78  AkUInt32 uSchedulerTypeFlags; ///< Scheduler type flags.
79  AkThreadProperties threadProperties; ///< Scheduler thread properties.
80  AkReal32 fTargetAutoStmBufferLength; ///< Targetted automatic stream buffer length (ms). When a stream reaches that buffering, it stops being scheduled for I/O except if the scheduler is idle.
81  AkUInt32 uMaxConcurrentIO; ///< Maximum number of transfers that can be sent simultaneously to the Low-Level I/O (applies to AK_SCHEDULER_DEFERRED_LINED_UP device only).
82  bool bUseStreamCache; ///< If true the device attempts to reuse IO buffers that have already been streamed from disk. This is particularly useful when streaming small looping sounds. The drawback is a small CPU hit when allocating memory, and a slightly larger memory footprint in the StreamManager pool.
83  AkUInt32 uMaxCachePinnedBytes; ///< Maximum number of bytes that can be "pinned" using AK::SoundEngine::PinEventInStreamCache() or AK::IAkStreamMgr::PinFileInCache()
84 };
85 
86 /// \name Scheduler type flags.
87 
88 /// Requests to Low-Level IO are synchronous. The streaming device expects a blocking I/O hook at creation time (IAkIOHookBlocking interface, see CreateDevice()).
89 /// Functions of this interface should return only when the transfer is complete.
90 #define AK_SCHEDULER_BLOCKING (0x01)
91 /// Requests to Low-Level IO are asynchronous, but posted one after the other, starting with streams that need data the most.
92 /// The streaming device expects a deferred I/O hook at creation time (IAkIOHookDeferred interface, see CreateDevice()).
93 /// Up to AkDeviceSettings::uMaxConcurrentIO requests can be sent to the Low-Level I/O at the same time.
94 #define AK_SCHEDULER_DEFERRED_LINED_UP (0x02)
95 
96 /// File descriptor. File identification for the low-level I/O.
97 /// \sa
98 /// - AK::StreamMgr::IAkLowLevelIOHook
99 struct AkFileDesc
100 {
101  AkInt64 iFileSize; ///< File size in bytes
102  AkUInt32 uSector; ///< Start sector (the sector size is specified by the low-level I/O)
103  ///< \sa
104  ///< - AK::StreamMgr::IAkFileLocationResolver::Open()
105  ///< - AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize()
106  AkUInt32 uCustomParamSize; ///< Size of the custom parameter
107  void * pCustomParam; ///< Custom parameter
108  AkFileHandle hFile; ///< File handle/identifier
109  AkDeviceID deviceID; ///< Device ID, obtained from CreateDevice() \sa AK::IAkStreamMgr::CreateDevice()
110  CAkFilePackage* pPackage; ///< If this file is in a File Package, this will be the
111 };
112 
113 /// Structure for synchronous transfers handshaking with the Low-Level I/O. Used with blocking I/O hooks.
114 /// \sa AK::StreamMgr::IAkIOHookBlocking
116 {
117  AkUInt64 uFilePosition; ///< File offset where transfer should begin.
118  AkUInt32 uBufferSize; ///< Size of the buffer in which the I/O hook can write to.
119  AkUInt32 uRequestedSize; ///< Exact number of requested bytes for this transfer. Always equal to or smaller than uBufferSize.
120 };
121 
122 struct AkAsyncIOTransferInfo;
123 /// Callback function prototype definition used for asynchronous I/O transfers between the Stream Manager
124 /// and the Low-Level IO. Used with deferred I/O hooks.
125 /// Notes:
126 /// - If you return AK_Fail, all streams awaiting for this transfer are marked as invalid and will stop. An "IO error" notification is posted to the capture log.
127 /// - If the transfer was cancelled by the Stream Manager while it was in the Low-Level IO, you must return AK_Success, whether
128 /// you performed the operation or not. The Stream Manager knows that it was cancelled, so it will not try to use it after you call it back.
129 /// \sa
130 /// - AkAsyncIOTransferInfo
131 /// - AK::StreamMgr::IAkIOHookDeferred
132 AK_CALLBACK( void, AkIOCallback )(
133  AkAsyncIOTransferInfo * in_pTransferInfo, ///< Pointer to the AkAsyncIOTransferInfo structure that was passed to corresponding Read() or Write() call.
134  AKRESULT in_eResult ///< Result of transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
135  );
136 
137 /// Structure for asynchronous transfers handshaking with the Low-Level I/O. Extends AkIOTransferInfo.
138 /// \sa
139 /// - AK::StreamMgr::IAkIOHookDeferred
140 /// - AkIOTransferInfo
141 /// - AkAIOCallback
143 {
144  void * pBuffer; ///< Buffer for data transfer.
145  AkIOCallback pCallback; ///< Callback function used to notify the high-level device when the transfer is complete.
146  void * pCookie; ///< Reserved. The I/O device uses this cookie to retrieve the owner of the transfer.
147  void * pUserData; ///< Custom user data.
148 };
149 
150 /// Low-Level I/O requests heuristics.
151 /// Used for asynchronous read requests.
152 /// \sa
153 /// - AK::StreamMgr::IAkIOHookBlocking::Read()
154 /// - AK::StreamMgr::IAkIOHookBlocking::Write()
155 /// - AK::StreamMgr::IAkIOHookDeferred::Read()
156 /// - AK::StreamMgr::IAkIOHookDeferred::Write()
158 {
159  AkReal32 fDeadline; ///< Operation deadline (ms).
160  AkPriority priority; ///< Operation priority (at the time it was scheduled and sent to the Low-Level I/O). Range is [AK_MIN_PRIORITY,AK_MAX_PRIORITY], inclusively.
161 };
162 
163 
164 
165 //@}
166 
167 namespace AK
168 {
169  // Audiokinetic Stream Manager's implementation-specific interfaces of the Low-Level IO submodule.
170  namespace StreamMgr
171  {
172  /// Base interface for Low-Level I/O hooks. Defines common methods across both types of hooks.
174  {
175  protected:
176  /// Virtual destructor on interface to avoid warnings.
177  virtual ~IAkLowLevelIOHook(){}
178 
179  public:
180  /// Cleans up a file.
181  /// \return AK_Success if the file was properly cleaned-up.
182  virtual AKRESULT Close(
183  AkFileDesc & in_fileDesc ///< File descriptor.
184  ) = 0;
185 
186  /// Returns the block size for the file or its storage device.
187  /// The block size is a constraint for clients
188  /// of the Stream Manager: All reads, writes and position changes need to be a multiple of
189  /// that size.
190  /// \return
191  /// The block size for a specific file or storage device.
192  /// \remarks
193  /// - Some files might be opened with flags that require I/O transfers to be a multiple
194  /// of this size. The stream manager will query this function to resolve calls
195  /// to IAk(Auto)Stream::GetBlockSize( ).
196  /// - Also, AkFileDesc::uSector specifies a number of sectors in multiples of this value.
197  /// - Files/IO devices that do not require byte alignment should return 1.
198  /// - Whether file opening was deferred or not, GetBlockSize() is always called right
199  /// after the first call to Open(), in the client's thread, and is never called again.
200  /// \warning
201  /// Returning 0 is not allowed and will likely make the Stream Manager crash.
202  /// \sa
203  /// - AK::StreamMgr::IAkFileLocationResolver::Open()
204  /// - AK::StreamMgr::IAkIOHookBlocking::Read()
205  /// - AK::StreamMgr::IAkIOHookBlocking::Write()
206  /// - AK::StreamMgr::IAkIOHookDeferred::Read()
207  /// - AK::StreamMgr::IAkIOHookDeferred::Write()
208  virtual AkUInt32 GetBlockSize(
209  AkFileDesc & in_fileDesc ///< File descriptor.
210  ) = 0;
211 
212  /// Returns a description for the streaming device above this low-level hook.
213  /// \remarks For profiling purposes only. The Release configuration of the
214  /// Stream Manager never calls it.
215  virtual void GetDeviceDesc(
216  AkDeviceDesc & out_deviceDesc ///< Device description.
217  ) = 0;
218 
219  /// Returns custom profiling data for the streaming device above this low-level hook.
220  /// As opposed to GetDeviceDesc(), this is called at every monitoring frame.
221  /// You may implement this function in order to display any value you find useful
222  /// in the "Streaming Devices" tab of the Wwise profiler ("Custom Param" column).
223  /// \remarks For profiling purposes only. The Release configuration of the
224  /// Stream Manager never calls it.
225  /// \return A 32-bit unsigned value to display in the Wwise profiler.
226  virtual AkUInt32 GetDeviceData() = 0;
227  };
228 
229  /// Interface for blocking low-level I/O transfers. Used by streaming devices created with the
230  /// AK_SCHEDULER_BLOCKING flag.
231  /// This is the simplest I/O hook. Calls to Read()/Write() must block until they are completed.
232  /// The streaming device's I/O thread sends one transfer at a time.
234  {
235  protected:
236  /// Virtual destructor on interface to avoid warnings.
237  virtual ~IAkIOHookBlocking(){}
238 
239  public:
240 
241  /// Reads data from a file (synchronous).
242  /// Read data from the file described by in_fileDesc, in address out_pBuffer and with size and position
243  /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
244  /// \remarks
245  /// File position passed in io_transferInfo takes the offset of this file relative
246  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
247  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
248  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
249  /// \return
250  /// - AK_Success: transfer was successful and out_pBuffer is filled with data.
251  /// - AK_Fail: an error occured.
252  virtual AKRESULT Read(
253  AkFileDesc & in_fileDesc, ///< File descriptor.
254  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
255  void * out_pBuffer, ///< Buffer to be filled with data.
256  AkIOTransferInfo & in_transferInfo ///< Synchronous data transfer info.
257  ) = 0;
258 
259  /// Writes data to a file (synchronous).
260  /// Write data to the file described by in_fileDesc, from address in_pData and with size and position
261  /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
262  /// \remarks File position passed in io_transferInfo takes the offset of this file relative
263  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
264  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
265  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
266  /// \return
267  /// - AK_Success: transfer was successful.
268  /// - AK_Fail: an error occured.
269  virtual AKRESULT Write(
270  AkFileDesc & in_fileDesc, ///< File descriptor.
271  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
272  void * in_pData, ///< Data to be written.
273  AkIOTransferInfo & io_transferInfo ///< Synchronous data transfer info.
274  ) = 0;
275  };
276 
277  /// Interface for deferred low-level I/O transfers. Used by streaming devices created with the
278  /// AK_SCHEDULER_DEFERRED_LINED_UP flag.
279  /// This I/O transfer handshaking method is preferred when you want to hook I/O to your own
280  /// I/O streaming technology. You will receive up to AkDeviceSettings::uMaxConcurrentIO requests
281  /// at the same time. You may queue them into your own system, and even use the heuristics passed
282  /// down to this level for your convenience.
283  /// Note that the requests are always sent in the order that the Stream Manager considers to be
284  /// the most appropriate. You may receive less than AkDeviceSettings::uMaxConcurrentIO at any
285  /// given time. The number of concurrent transfers depends on the number of streams running in
286  /// the high-level streaming device, and on its target buffering length and granularity.
287  /// Your advantage at this level is to be aware of file placement, so you may try to re-order
288  /// requests in order to minimize seeking on disk.
289  /// Calls to Read()/Write() should return as soon as possible. You need to call
290  /// AkAsyncIOTransferInfo::pCallback as soon as a transfer is completed.
291  /// Cancel() is provided in order to inform you that the streaming device will flush this transfer
292  /// upon completion. You may implement it or not. In all cases, you must call the callback.
294  {
295  protected:
296  /// Virtual destructor on interface to avoid warnings.
297  virtual ~IAkIOHookDeferred(){}
298 
299  public:
300 
301  /// Reads data from a file (asynchronous).
302  /// \remarks
303  /// - Queue up your read request with address, size and file position specified in io_transferInfo.
304  /// - When transfer is complete (whether it was successful, cancelled or failed), call
305  /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Read(), do not call
306  /// AkAsyncIOTransferInfo::pCallback.
307  /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
308  /// be changed by the Low-Level I/O.
309  /// - The reference to io_transferInfo will be valid until the high-level device is notified
310  /// through the callback.
311  /// - File position passed in io_transferInfo takes the offset of this file relative
312  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
313  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
314  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
315  /// \return
316  /// - AK_Success: An I/O request was successfully processed and is pending:
317  /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
318  /// - AK_Fail: an error occured.
319  virtual AKRESULT Read(
320  AkFileDesc & in_fileDesc, ///< File descriptor.
321  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
322  AkAsyncIOTransferInfo & io_transferInfo ///< Asynchronous data transfer info.
323  ) = 0;
324 
325  /// Writes data to a file (asynchronous).
326  /// \remarks
327  /// - Queue up your write request with address, size and file position specified in io_transferInfo.
328  /// - When transfer is complete (whether it was successful, cancelled or failed), call
329  /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Write(), do not call
330  /// AkAsyncIOTransferInfo::pCallback.
331  /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
332  /// be changed by the Low-Level I/O.
333  /// - The reference to io_transferInfo will be valid until the high-level device is notified
334  /// through the callback.
335  /// - File position passed in io_transferInfo takes the offset of this file relative
336  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
337  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
338  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
339  /// \return
340  /// - AK_Success: An I/O request was successfully processed and is pending:
341  /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
342  /// - AK_Fail: an error occured.
343  virtual AKRESULT Write(
344  AkFileDesc & in_fileDesc, ///< File descriptor.
345  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
346  AkAsyncIOTransferInfo & io_transferInfo ///< Platform-specific asynchronous IO operation info.
347  ) = 0;
348 
349  /// Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed.
350  /// Cancellation is normal and happens regularly; for example, whenever a sound stops before the end
351  /// or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength
352  /// and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests
353  /// at the same time.
354  /// \remarks
355  /// - Cancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception.
356  /// The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged
357  /// by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled
358  /// transfers to be resolved.
359  /// - When calling the callback function of a cancelled transfer, pass it *AK_Success*. Passing AK_Fail
360  /// to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not
361  /// what you want.
362  /// - If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once.
363  /// Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if
364  /// you don't do anything special in Cancel(), leave it to true. This will reduce the amount of useless calls.
365  /// If you set it to false, Cancel() will be called again for each remaining pending transfer that need to be cancelled.
366  /// - If io_bCancelAllTransfersForThisFile is not set, Cancel() is only called for a subset of pending
367  /// transfers for this file. You must not set it to true, as Cancel() needs to be called explicitly for each transfer that should be cancelled.
368  /// \warning
369  /// - The calling thread holds the stream's lock. You may call the callback function directly from here
370  /// (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here
371  /// for another thread to call the callback function.
372  /// - Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue,
373  /// be careful not to run into a deadlock. Cancel() can be executed by any thread. Thus, if you need to lock your queue
374  /// in Cancel(), you must never hold this lock when calling back transfers, either from within Cancel() or from your
375  /// worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if
376  /// the transfer was found and dequeued. On the other hand, if you choose not to do anything in Cancel(), the lock only protects
377  /// your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the
378  /// stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
379  /// - A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook.
380  /// If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later
381  /// (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
382  virtual void Cancel(
383  AkFileDesc & in_fileDesc, ///< File descriptor.
384  AkAsyncIOTransferInfo & io_transferInfo, ///< Transfer info to cancel.
385  bool & io_bCancelAllTransfersForThisFile ///< Flag indicating whether all transfers should be cancelled for this file (see notes in function description).
386  ) = 0;
387  };
388 
389  /// File location resolver interface. There is one and only one File Location Resolver that is
390  /// registered to the Stream Manager (using AK::StreamMgr::SetFileLocationResolver()). Its purpose
391  /// is to map a file name or ID to
392  /// 1) a streaming device / I/O hook;
393  /// 2) a valid file descriptor (AkFileDesc) usable by the I/O hook.
394  /// When your Low-Level I/O submodule uses a single device, you should create a standalone I/O
395  /// hook which implements one of the I/O hooks defined above (blocking or deferred), as well
396  /// as the File Location Resolver. You then register this object to the Stream Manager as the
397  /// File Location Resolver.
398  /// If you wish to create multiple devices, then you should have a separate object that implements
399  /// AK::StreamMgr::IAkFileLocationResolver and registers to the Stream Manager as such. This object
400  /// will be used to dispatch the file open request to the appropriate device. The strategy you will
401  /// use to select the correct device is up to you to implement. You may also implement a set of
402  /// hooks that delegate opening to the next device when they can't find the file requested
403  /// (like a chain of responsiblity pattern), although this will likely be less efficient.
405  {
406  protected:
407  /// Virtual destructor on interface to avoid warnings.
409 
410  public:
411 
412  /// Returns a file descriptor for a given file name (string).
413  /// Performs the operations needed to make the file descriptor usable by
414  /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
415  /// \return
416  /// - AK_Success: A valid file descriptor is returned
417  /// - AK_FileNotFound: File was not found.
418  /// - AK_Fail: File could not be open for any other reason.
419  /// \return
420  /// - A file descriptor, which contains
421  /// - an unique identifier to be used with functions of the low-level IO
422  /// interface.
423  /// - the total stream size in bytes.
424  /// - the offset from the beginning of the file (in blocks).
425  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
426  /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
427  /// \remarks
428  /// - The file descriptor is unique for each stream, and its address remains the same
429  /// throughout its lifetime. In other words, the value of &in_fileDesc inside Read() or
430  /// Close() is the same as &out_fileDesc in Open().
431  /// - Open() is always called first in the client thread.
432  /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
433  /// the File Location Resolver may choose whether it wants open it now, or later
434  /// from the streaming device's thread. If it wishes to open it now, then it must
435  /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
436  /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
437  /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
438  /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
439  /// this as a request for deferred file opening, and this function will called again
440  /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
441  /// - All members of out_fileDesc will be cleared upon first call to Open().
442  /// \warning
443  /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
444  /// set to true.
445  /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
446  /// The File Location Resolver should always choose to open files synchronously if it is
447  /// fast to do so.
448  /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
449  /// first call to Open(), in the client's thread, and is never called again.
450  /// \sa
451  /// - GetBlockSize()
452  /// - \ref streamingmanager_lowlevel_location
453  virtual AKRESULT Open(
454  const AkOSChar* in_pszFileName, ///< File name.
455  AkOpenMode in_eOpenMode, ///< Open mode.
456  AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
457  bool & io_bSyncOpen, ///< If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
458  AkFileDesc & io_fileDesc ///< Returned file descriptor.
459  ) = 0;
460 
461  /// Returns a file descriptor for a given file ID.
462  /// Performs the operations needed to make the file descriptor usable by
463  /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
464  /// \return
465  /// - AK_Success: A valid file descriptor is returned
466  /// - AK_FileNotFound: File was not found.
467  /// - AK_Fail: File could not be open for any other reason.
468  /// \return
469  /// - A file descriptor, which contains
470  /// - an unique identifier to be used with functions of the low-level IO
471  /// interface.
472  /// - the total stream size in bytes.
473  /// - the offset of the beginning of the file (in blocks).
474  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
475  /// - A file descriptor, that contains
476  /// - an unique identifier to be used with functions of the low-level IO
477  /// interface.
478  /// - the total stream size in bytes.
479  /// - the offset from the beginning of the file (in blocks).
480  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
481  /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
482  /// \remarks
483  /// - Open() is always called first in the client thread.
484  /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
485  /// the File Location Resolver may choose whether it wants open it now, or later
486  /// from the streaming device's thread. If it wishes to open it now, then it must
487  /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
488  /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
489  /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
490  /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
491  /// this as a request for deferred file opening, and this function will called again
492  /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
493  /// - All members of out_fileDesc will be cleared upon first call to Open().
494  /// \warning
495  /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
496  /// set to true.
497  /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
498  /// The File Location Resolver should always choose to open files synchronously if it is
499  /// fast to do so.
500  /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
501  /// first call to Open(), in the client's thread, and is never called again.
502  /// - GetBlockSize()
503  /// - \ref streamingmanager_lowlevel_location
504  virtual AKRESULT Open(
505  AkFileID in_fileID, ///< File ID.
506  AkOpenMode in_eOpenMode, ///< Open mode.
507  AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
508  bool & io_bSyncOpen, ///< If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
509  AkFileDesc & io_fileDesc ///< Returned file descriptor.
510  ) = 0;
511  };
512 
513  /// \name Audiokinetic implementation-specific Stream Manager factory.
514  //@{
515  /// Stream Manager factory.
516  /// \remarks
517  /// - In order for the Stream Manager to work properly, you also need to create
518  /// at least one streaming device (and implement its I/O hook), and register the
519  /// File Location Resolver with AK::StreamMgr::SetFileLocationResolver().
520  /// - Use AK::StreamMgr::GetDefaultSettings(), then modify the settings you want,
521  /// then feed this function with them.
522  /// \sa
523  /// - AK::IAkStreamMgr
524  /// - AK::StreamMgr::SetFileLocationResolver()
525  /// - AK::StreamMgr::GetDefaultSettings()
526  AK_EXTERNAPIFUNC( IAkStreamMgr *, Create )(
527  const AkStreamMgrSettings & in_settings ///< Stream manager initialization settings.
528  );
529 
530  /// Get the default values for the Stream Manager's settings.
531  /// \sa
532  /// - AK::StreamMgr::Create()
533  /// - AkStreamMgrSettings
534  /// - \ref streamingmanager_settings
535  AK_EXTERNAPIFUNC( void, GetDefaultSettings )(
536  AkStreamMgrSettings & out_settings ///< Returned AkStreamMgrSettings structure with default values.
537  );
538 
539  /// Get the one and only File Location Resolver registered to the Stream Manager.
540  /// \sa
541  /// - AK::StreamMgr::IAkFileLocationResolver
542  /// - AK::StreamMgr::SetFileLocationResolver()
544 
545  /// Register the one and only File Location Resolver to the Stream Manager.
546  /// \sa
547  /// - AK::StreamMgr::IAkFileLocationResolver
548  AK_EXTERNAPIFUNC( void, SetFileLocationResolver )(
549  IAkFileLocationResolver * in_pFileLocationResolver ///< Interface to your File Location Resolver
550  );
551 
552  /// Get the Stream Manager's pool ID, created according to setting
553  /// AkStreamMgrSettings::uMemorySize.
554  /// \remarks This is the small objects pool, not one of the device ("Stream I/O") pools.
555  /// \sa
556  /// - AkStreamMgrSettings
557  /// - AK::StreamMgr::Create()
558  AK_EXTERNAPIFUNC( AkMemPoolId, GetPoolID )();
559 
560  //@}
561 
562  /// \name Stream Manager: High-level I/O devices management.
563  //@{
564  /// Streaming device creation.
565  /// Creates a high-level device, with specific settings.
566  /// You need to provide the associated low-level I/O hook, implemented on your side.
567  /// \return The device ID. AK_INVALID_DEVICE_ID if there was an error and it could not be created.
568  /// \warning
569  /// - This function is not thread-safe.
570  /// - Use a blocking hook (IAkIOHookBlocking) with SCHEDULER_BLOCKING devices, and a
571  /// deferred hook (IAkIOHookDeferred) with SCHEDULER_DEFERRED_LINED_UP devices (these flags are
572  /// specified in the device settings (AkDeviceSettings). The pointer to IAkLowLevelIOHook is
573  /// statically cast internally into one of these hooks. Implementing the wrong (or no) interface
574  /// will result into a crash.
575  /// \remarks
576  /// - You may use AK::StreamMgr::GetDefaultDeviceSettings() first to get default values for the
577  /// settings, change those you want, then feed the structure to this function.
578  /// - The returned device ID should be kept by the Low-Level IO, to assign it to file descriptors
579  /// in AK::StreamMgr::IAkFileLocationResolver::Open().
580  /// \sa
581  /// - AK::StreamMgr::IAkLowLevelIOHook
582  /// - AK::StreamMgr::GetDefaultDeviceSettings()
583  /// - \ref streamingmanager_settings
584  AK_EXTERNAPIFUNC( AkDeviceID, CreateDevice )(
585  const AkDeviceSettings & in_settings, ///< Device settings.
586  IAkLowLevelIOHook * in_pLowLevelHook ///< Associated low-level I/O hook. Pass either a IAkIOHookBlocking or a IAkIOHookDeferred interface, consistent with the type of the scheduler.
587  );
588  /// Streaming device destruction.
589  /// \return AK_Success if the device was successfully destroyed.
590  /// \warning This function is not thread-safe. No stream should exist for that device when it is destroyed.
591  AK_EXTERNAPIFUNC( AKRESULT, DestroyDevice )(
592  AkDeviceID in_deviceID ///< Device ID of the device to destroy.
593  );
594 
595  /// Get the default values for the streaming device's settings. Recommended usage
596  /// is to call this function first, then pass the settings to AK::StreamMgr::CreateDevice().
597  /// \sa
598  /// - AK::StreamMgr::CreateDevice()
599  /// - AkDeviceSettings
600  /// - \ref streamingmanager_settings
601  AK_EXTERNAPIFUNC( void, GetDefaultDeviceSettings )(
602  AkDeviceSettings & out_settings ///< Returned AkDeviceSettings structure with default values.
603  );
604  //@}
605 
606  /// \name Language management.
607  //@{
608  /// Set the current language once and only once, here. The language name is stored in a static buffer
609  /// inside the Stream Manager. In order to resolve localized (language-specific) file location,
610  /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
611  /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
612  /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
613  /// Pass a valid null-terminated string, without a trailing slash or backslash. Empty strings are accepted.
614  /// You may register for language changes (see RegisterToLanguageChangeNotification()).
615  /// After changing the current language, all observers are notified.
616  /// \return AK_Success if successful (if language string has less than AK_MAX_LANGUAGE_NAME_SIZE characters). AK_Fail otherwise.
617  /// \warning Not multithread safe.
618  /// \sa
619  /// - AK::StreamMgr::GetCurrentLanguage()
620  /// - AK::StreamMgr::AddLanguageChangeObserver()
621  AK_EXTERNAPIFUNC( AKRESULT, SetCurrentLanguage )(
622  const AkOSChar * in_pszLanguageName ///< Language name.
623  );
624 
625  /// Get the current language. The language name is stored in a static buffer inside the Stream Manager,
626  /// with AK::StreamMgr::SetCurrentLanguage(). In order to resolve localized (language-specific) file location,
627  /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
628  /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
629  /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
630  /// \return Current language.
631  /// \sa AK::StreamMgr::SetCurrentLanguage()
632  AK_EXTERNAPIFUNC( const AkOSChar *, GetCurrentLanguage )();
633 
634  /// Definition of handlers for language change notifications.
635  /// Called after SetCurrentLanguage() is called.
636  /// \warning Do not call AddLanguageChangeObserver or SetCurrentLanguage from within your handler.
637  /// \warning Not multithread safe.
638  /// \sa
639  /// - AK::StreamMgr::SetCurrentLanguage()
640  /// - AK::StreamMgr::AddLanguageChangeObserver()
641  AK_CALLBACK( void, AkLanguageChangeHandler )(
642  const AkOSChar * const in_pLanguageName,///< New language name.
643  void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
644  );
645 
646  /// Register to language change notifications.
647  /// \return AK_Success if successful, AK_Fail otherwise (no memory or no cookie).
648  /// \warning Not multithread safe.
649  /// \sa
650  /// - AK::StreamMgr::SetCurrentLanguage()
651  /// - AK::StreamMgr::RemoveLanguageChangeObserver()
652  AK_EXTERNAPIFUNC( AKRESULT, AddLanguageChangeObserver )(
653  AkLanguageChangeHandler in_handler, ///< Callback function.
654  void * in_pCookie ///< Cookie, passed back to AkLanguageChangeHandler. Must set.
655  );
656 
657  /// Unregister to language change notifications. Use the cookie you have passed to
658  /// AddLanguageChangeObserver() to identify the observer.
659  /// \warning Not multithread safe.
660  /// \sa
661  /// - AK::StreamMgr::SetCurrentLanguage()
662  /// - AK::StreamMgr::AddLanguageChangeObserver()
663  AK_EXTERNAPIFUNC( void, RemoveLanguageChangeObserver )(
664  void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
665  );
666 
667  /// \name Stream Manager: Cache management.
668  //@{
669  /// Flush cache of all devices. This function has no effect for devices where
670  /// AkDeviceSettings::bUseStreamCache was set to false (no caching).
671  /// \sa
672  /// - \ref streamingmanager_settings
673  AK_EXTERNAPIFUNC( void, FlushAllCaches )();
674 
675  //@}
676  }
677 }
678 
679 #endif //_AK_STREAM_MGR_MODULE_H_
void * pCookie
Reserved. The I/O device uses this cookie to retrieve the owner of the transfer.
virtual ~IAkIOHookDeferred()
Virtual destructor on interface to avoid warnings.
AkUInt32 uIOMemoryAlignment
I/O memory pool alignment. It is passed directly to AK::MemoryMgr::CreatePool().
Base interface for Low-Level I/O hooks. Defines common methods across both types of hooks.
AkReal32 fDeadline
Operation deadline (ms).
Audiokinetic namespace.
void * pCustomParam
Custom parameter.
AKSOUNDENGINE_API AKRESULT DestroyDevice(AkDeviceID in_deviceID)
AKSOUNDENGINE_API AKRESULT SetCurrentLanguage(const AkOSChar *in_pszLanguageName)
virtual AKRESULT Open(const AkOSChar *in_pszFileName, AkOpenMode in_eOpenMode, AkFileSystemFlags *in_pFlags, bool &io_bSyncOpen, AkFileDesc &io_fileDesc)=0
virtual AkUInt32 GetDeviceData()=0
void(* AkLanguageChangeHandler)(const AkOSChar *const in_pLanguageName, void *in_pCookie)
AkUInt32 uMaxCachePinnedBytes
Maximum number of bytes that can be "pinned" using AK::SoundEngine::PinEventInStreamCache() or AK::IA...
void * pUserData
Custom user data.
AkUInt32 uRequestedSize
Exact number of requested bytes for this transfer. Always equal to or smaller than uBufferSize.
AKSOUNDENGINE_API AkMemPoolId GetPoolID()
AkUInt32 uMaxConcurrentIO
Maximum number of transfers that can be sent simultaneously to the Low-Level I/O (applies to AK_SCHED...
AkUInt32 uMemorySize
AkReal32 fTargetAutoStmBufferLength
Targetted automatic stream buffer length (ms). When a stream reaches that buffering,...
bool bUseStreamCache
If true the device attempts to reuse IO buffers that have already been streamed from disk....
AKSOUNDENGINE_API void GetDefaultSettings(AkStreamMgrSettings &out_settings)
virtual ~IAkLowLevelIOHook()
Virtual destructor on interface to avoid warnings.
virtual AKRESULT Open(AkFileID in_fileID, AkOpenMode in_eOpenMode, AkFileSystemFlags *in_pFlags, bool &io_bSyncOpen, AkFileDesc &io_fileDesc)=0
AkDeviceID deviceID
Device ID, obtained from CreateDevice()
AkPriority priority
Operation priority (at the time it was scheduled and sent to the Low-Level I/O). Range is [AK_MIN_PRI...
AkUInt32 uSchedulerTypeFlags
Scheduler type flags.
AkUInt32 uBufferSize
Size of the buffer in which the I/O hook can write to.
virtual void Cancel(AkFileDesc &in_fileDesc, AkAsyncIOTransferInfo &io_transferInfo, bool &io_bCancelAllTransfersForThisFile)=0
void * pBuffer
Buffer for data transfer.
AKSOUNDENGINE_API AkDeviceID CreateDevice(const AkDeviceSettings &in_settings, IAkLowLevelIOHook *in_pLowLevelHook)
AkUInt32 uGranularity
I/O requests granularity (typical bytes/request).
virtual void GetDeviceDesc(AkDeviceDesc &out_deviceDesc)=0
AkUInt32 uSector
CAkFilePackage * pPackage
If this file is in a File Package, this will be the.
File system flags for file descriptors mapping.
Definition: IAkStreamMgr.h:82
virtual AkUInt32 GetBlockSize(AkFileDesc &in_fileDesc)=0
virtual AKRESULT Close(AkFileDesc &in_fileDesc)=0
AkIOCallback pCallback
Callback function used to notify the high-level device when the transfer is complete.
virtual AKRESULT Read(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, AkAsyncIOTransferInfo &io_transferInfo)=0
AKSOUNDENGINE_API IAkFileLocationResolver * GetFileLocationResolver()
AKSOUNDENGINE_API IAkStreamMgr * Create(const AkStreamMgrSettings &in_settings)
AKSOUNDENGINE_API void FlushAllCaches()
Device descriptor.
Definition: IAkStreamMgr.h:150
virtual AKRESULT Write(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, void *in_pData, AkIOTransferInfo &io_transferInfo)=0
AKSOUNDENGINE_API void GetDefaultDeviceSettings(AkDeviceSettings &out_settings)
virtual AKRESULT Read(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, void *out_pBuffer, AkIOTransferInfo &in_transferInfo)=0
AKSOUNDENGINE_API void SetFileLocationResolver(IAkFileLocationResolver *in_pFileLocationResolver)
AkUInt32 uCustomParamSize
Size of the custom parameter.
AkMemPoolAttributes ePoolAttributes
Attributes for internal I/O memory pool. Note that these pools are always allocated internally as AkF...
AKSOUNDENGINE_API void RemoveLanguageChangeObserver(void *in_pCookie)
AKSOUNDENGINE_API AKRESULT AddLanguageChangeObserver(AkLanguageChangeHandler in_handler, void *in_pCookie)
AkUInt64 uFilePosition
File offset where transfer should begin.
virtual ~IAkFileLocationResolver()
Virtual destructor on interface to avoid warnings.
virtual ~IAkIOHookBlocking()
Virtual destructor on interface to avoid warnings.
AkUInt32 uIOMemorySize
Size of memory pool for I/O (for automatic streams). It is passed directly to AK::MemoryMgr::CreatePo...
AkFileHandle hFile
File handle/identifier.
AkInt64 iFileSize
File size in bytes.
virtual AKRESULT Write(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, AkAsyncIOTransferInfo &io_transferInfo)=0
AKSOUNDENGINE_API const AkOSChar * GetCurrentLanguage()
AkThreadProperties threadProperties
Scheduler thread properties.

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise