Table of Contents

Wwise SDK 2019.2.4
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 };
55 
56 /// High-level IO devices initialization settings.
57 /// \sa
58 /// - AK::IAkStreamMgr
59 /// - AK::StreamMgr::CreateDevice()
60 /// - \ref streamingmanager_settings
62 {
63  void * pIOMemory; ///< Pointer for I/O memory allocated by user.
64  ///< Pass NULL if you want memory to be allocated via AK::MemoryMgr::Malign().
65  ///< If specified, uIOMemorySize, uIOMemoryAlignment and ePoolAttributes are ignored.
66  AkUInt32 uIOMemorySize; ///< Size of memory for I/O (for automatic streams). It is passed directly to AK::MemoryMgr::Malign(), after having been rounded down to a multiple of uGranularity.
67  AkUInt32 uIOMemoryAlignment; ///< I/O memory alignment. It is passed directly to AK::MemoryMgr::Malign().
68  AkUInt32 ePoolAttributes; ///< Attributes for I/O memory. Here, specify the allocation type (AkMemType_Device, and so on). It is passed directly to AK::MemoryMgr::Malign().
69  AkUInt32 uGranularity; ///< I/O requests granularity (typical bytes/request).
70  AkUInt32 uSchedulerTypeFlags; ///< Scheduler type flags.
71  AkThreadProperties threadProperties; ///< Scheduler thread properties.
72  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.
73  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).
74  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.
75  AkUInt32 uMaxCachePinnedBytes; ///< Maximum number of bytes that can be "pinned" using AK::SoundEngine::PinEventInStreamCache() or AK::IAkStreamMgr::PinFileInCache()
76 };
77 
78 /// \name Scheduler type flags.
79 
80 /// Requests to Low-Level IO are synchronous. The streaming device expects a blocking I/O hook at creation time (IAkIOHookBlocking interface, see CreateDevice()).
81 /// Functions of this interface should return only when the transfer is complete.
82 #define AK_SCHEDULER_BLOCKING (0x01)
83 /// Requests to Low-Level IO are asynchronous, but posted one after the other, starting with streams that need data the most.
84 /// The streaming device expects a deferred I/O hook at creation time (IAkIOHookDeferredBatch interface, see CreateDevice()).
85 /// Up to AkDeviceSettings::uMaxConcurrentIO requests can be sent to the Low-Level I/O at the same time.
86 #define AK_SCHEDULER_DEFERRED_LINED_UP (0x02)
87 
88 /// File descriptor. File identification for the low-level I/O.
89 /// \sa
90 /// - AK::StreamMgr::IAkLowLevelIOHook
91 struct AkFileDesc
92 {
93  AkInt64 iFileSize; ///< File size in bytes
94  AkUInt32 uSector; ///< Start sector (the sector size is specified by the low-level I/O)
95  ///< \sa
96  ///< - AK::StreamMgr::IAkFileLocationResolver::Open()
97  ///< - AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize()
98  AkUInt32 uCustomParamSize; ///< Size of the custom parameter
99  void * pCustomParam; ///< Custom parameter
100  AkFileHandle hFile; ///< File handle/identifier
101  AkDeviceID deviceID; ///< Device ID, obtained from CreateDevice() \sa AK::IAkStreamMgr::CreateDevice()
102  CAkFilePackage* pPackage; ///< If this file is in a File Package, this will be the
103 };
104 
105 /// Structure for synchronous transfers handshaking with the Low-Level I/O. Used with blocking I/O hooks.
106 /// \sa AK::StreamMgr::IAkIOHookBlocking
108 {
109  AkUInt64 uFilePosition; ///< File offset where transfer should begin.
110  AkUInt32 uBufferSize; ///< Size of the buffer in which the I/O hook can write to.
111  AkUInt32 uRequestedSize; ///< Exact number of requested bytes for this transfer. Always equal to or smaller than uBufferSize.
112 };
113 
114 struct AkAsyncIOTransferInfo;
115 
116 /// Callback function prototype definition used for asynchronous I/O transfers between the Stream Manager
117 /// and the Low-Level IO. Used with deferred I/O hooks.
118 /// Notes:
119 /// - If you pass in_eResult of 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.
120 /// - If the transfer was cancelled by the Stream Manager while it was in the Low-Level IO, you must return AK_Success, whether
121 /// 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.
122 /// \sa
123 /// - AkAsyncIOTransferInfo
124 /// - AK::StreamMgr::IAkIOHookDeferredBatch
125 AK_CALLBACK( void, AkIOCallback )(
126  AkAsyncIOTransferInfo * in_pTransferInfo, ///< Pointer to the AkAsyncIOTransferInfo structure that was passed to corresponding Read() or Write() call.
127  AKRESULT in_eResult ///< Result of transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
128  );
129 
130 /// Callback function prototype definition used for asynchronous I/O transfers between the Stream Manager
131 /// and the Low-Level IO. Used with batch deferred I/O hooks.
132 /// Notes:
133 /// - in_peResult and in_ppTransferInfo must both contain in_uNumTransfers number of elements
134 /// - For each in_peResult with a value of AK_Fail, all streams awaiting for the corresponding transfer are marked as invalid and will stop. An "IO error" notification is posted to the capture log.
135 /// - If a given transfer was cancelled by the Stream Manager while it was in the Low-Level IO, you must return AK_Success for that result, whether
136 /// 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.
137 /// - Note that one call to BatchRead, BatchWrite or BatchCancel does not have to result in one execution of the callback. The only requirement is that
138 /// each element of in_ppTransferInfo passed in only has the IOCallback fired on it one time.
139 /// \sa
140 /// - AkAsyncIOTransferInfo
141 /// - AK::StreamMgr::IAkIOHookDeferredBatch
142 AK_CALLBACK(void, AkBatchIOCallback)(
143  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
144  AkAsyncIOTransferInfo** in_ppTransferInfo, ///< List of pointers to AkAsyncIOTransferInfo structures that were previously passed in to BatchRead() or BatchWrite()
145  AKRESULT* in_peResult ///< Array of results of each transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
146  );
147 
148 /// Structure for asynchronous transfers handshaking with the Low-Level I/O. Extends AkIOTransferInfo.
149 /// \sa
150 /// - AK::StreamMgr::IAkIOHookDeferredBatch
151 /// - AkIOTransferInfo
152 /// - AkAIOCallback
154 {
155  void * pBuffer; ///< Buffer for data transfer.
156  AkIOCallback pCallback; ///< Callback function used to notify the high-level device when the transfer is complete.
157  void * pCookie; ///< Reserved. The I/O device uses this cookie to retrieve the owner of the transfer.
158  void * pUserData; ///< Custom user data.
159 };
160 
161 /// Low-Level I/O requests heuristics.
162 /// Used for asynchronous read requests.
163 /// \sa
164 /// - AK::StreamMgr::IAkIOHookBlocking::Read()
165 /// - AK::StreamMgr::IAkIOHookBlocking::Write()
166 /// - AK::StreamMgr::IAkIOHookDeferredBatch::Read()
167 /// - AK::StreamMgr::IAkIOHookDeferredBatch::Write()
169 {
170  AkReal32 fDeadline; ///< Operation deadline (ms).
171  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.
172 };
173 
174 
175 
176 //@}
177 
178 namespace AK
179 {
180  // Audiokinetic Stream Manager's implementation-specific interfaces of the Low-Level IO submodule.
181  namespace StreamMgr
182  {
183  /// Base interface for Low-Level I/O hooks. Defines common methods across both types of hooks.
185  {
186  protected:
187  /// Virtual destructor on interface to avoid warnings.
188  virtual ~IAkLowLevelIOHook(){}
189 
190  public:
191  /// Cleans up a file.
192  /// \return AK_Success if the file was properly cleaned-up.
193  virtual AKRESULT Close(
194  AkFileDesc & in_fileDesc ///< File descriptor.
195  ) = 0;
196 
197  /// Returns the block size for the file or its storage device.
198  /// The block size is a constraint for clients
199  /// of the Stream Manager: All reads, writes and position changes need to be a multiple of
200  /// that size.
201  /// \return
202  /// The block size for a specific file or storage device.
203  /// \remarks
204  /// - Some files might be opened with flags that require I/O transfers to be a multiple
205  /// of this size. The stream manager will query this function to resolve calls
206  /// to IAk(Auto)Stream::GetBlockSize( ).
207  /// - Also, AkFileDesc::uSector specifies a number of sectors in multiples of this value.
208  /// - Files/IO devices that do not require byte alignment should return 1.
209  /// - Whether file opening was deferred or not, GetBlockSize() is always called right
210  /// after the first call to Open(), in the client's thread, and is never called again.
211  /// \warning
212  /// Returning 0 is not allowed and will likely make the Stream Manager crash.
213  /// \sa
214  /// - AK::StreamMgr::IAkFileLocationResolver::Open()
215  /// - AK::StreamMgr::IAkIOHookBlocking::Read()
216  /// - AK::StreamMgr::IAkIOHookBlocking::Write()
217  /// - AK::StreamMgr::IAkIOHookDeferredBatch::Read()
218  /// - AK::StreamMgr::IAkIOHookDeferredBatch::Write()
219  virtual AkUInt32 GetBlockSize(
220  AkFileDesc & in_fileDesc ///< File descriptor.
221  ) = 0;
222 
223  /// Returns a description for the streaming device above this low-level hook.
224  /// \remarks For profiling purposes only. The Release configuration of the
225  /// Stream Manager never calls it.
226  virtual void GetDeviceDesc(
227  AkDeviceDesc & out_deviceDesc ///< Device description.
228  ) = 0;
229 
230  /// Returns custom profiling data for the streaming device above this low-level hook.
231  /// As opposed to GetDeviceDesc(), this is called at every monitoring frame.
232  /// You may implement this function in order to display any value you find useful
233  /// in the "Streaming Devices" tab of the Wwise profiler ("Custom Param" column).
234  /// \remarks For profiling purposes only. The Release configuration of the
235  /// Stream Manager never calls it.
236  /// \return A 32-bit unsigned value to display in the Wwise profiler.
237  virtual AkUInt32 GetDeviceData() = 0;
238  };
239 
240  /// Interface for blocking low-level I/O transfers. Used by streaming devices created with the
241  /// AK_SCHEDULER_BLOCKING flag.
242  /// This is the simplest I/O hook. Calls to Read()/Write() must block until they are completed.
243  /// The streaming device's I/O thread sends one transfer at a time.
245  {
246  protected:
247  /// Virtual destructor on interface to avoid warnings.
248  virtual ~IAkIOHookBlocking(){}
249 
250  public:
251 
252  /// Reads data from a file (synchronous).
253  /// Read data from the file described by in_fileDesc, in address out_pBuffer and with size and position
254  /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
255  /// \remarks
256  /// File position passed in io_transferInfo takes the offset of this file relative
257  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
258  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
259  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
260  /// \return
261  /// - AK_Success: transfer was successful and out_pBuffer is filled with data.
262  /// - AK_Fail: an error occured.
263  virtual AKRESULT Read(
264  AkFileDesc & in_fileDesc, ///< File descriptor.
265  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
266  void * out_pBuffer, ///< Buffer to be filled with data.
267  AkIOTransferInfo & in_transferInfo ///< Synchronous data transfer info.
268  ) = 0;
269 
270  /// Writes data to a file (synchronous).
271  /// Write data to the file described by in_fileDesc, from address in_pData and with size and position
272  /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
273  /// \remarks File position passed in io_transferInfo takes the offset of this file relative
274  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
275  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
276  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
277  /// \return
278  /// - AK_Success: transfer was successful.
279  /// - AK_Fail: an error occured.
280  virtual AKRESULT Write(
281  AkFileDesc & in_fileDesc, ///< File descriptor.
282  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
283  void * in_pData, ///< Data to be written.
284  AkIOTransferInfo & io_transferInfo ///< Synchronous data transfer info.
285  ) = 0;
286  };
287 
288  /// Interface for batched deferred low-level I/O transfers. Used by streaming devices created
289  /// with the AK_SCHEDULER_DEFERRED_LINED_UP flag.
290  /// This I/O transfer handshaking method is preferred when you want to hook I/O to your own
291  /// I/O streaming technology, and you want to submit multiple I/O requests in one call, so as
292  /// to allow for better opportunities for CPU and I/O performance.
293  /// You may queue them into your own system, and even use the heuristics passed down to this
294  /// level for your convenience. Note that the requests are always sent in the order that the
295  /// Stream Manager considers to be the most appropriate. You may receive less than
296  /// AkDeviceSettings::uMaxConcurrentIO at any given time. The number of concurrent transfers
297  /// depends on the number of streams running in the high-level streaming device, and on its
298  /// target buffering length and granularity. Your advantage at this level is to be aware of
299  /// file placement, so you may try to re-order requests in order to minimize seeking on disk.
300  /// Calls to BatchRead()/BatchWrite() should return as soon as possible. You need to call
301  /// AkAsyncIOTransferInfo::pCallback for an individual item, or AkBatchIOCallback for a collection
302  /// of items as soon as a transfer is completed.
303  /// Cancel() is provided in order to inform you that the streaming device will flush this transfer
304  /// upon completion. You may implement it or not. In all cases, you must call the callback.
306  {
307  protected:
308  /// Virtual destructor on interface to avoid warnings.
310 
311  public:
313  {
317  };
318 
319  /// Reads multiple data from multiple files (asynchronous).
320  /// \remarks
321  /// - Queue up multiple read requests at once, using the provided array of in_pTransferItems. There will
322  /// be in_uNumTransfers number of items in the array.
323  /// - io_pDispatchResults will contain an in_uNumTransfers number of items in the array. Each item in
324  /// io_pDispatchResults should be set to AK_Success if the corresponding Read was successfully dispatched,
325  /// and set to AK_Failure otherwise. As well, the return value should be a cumulative result of the
326  /// dispatches, where AK_Success indicates all requests were dispatched successfully, and
327  /// io_pDispatchResults will not be investigated, whereas AK_Fail indicates at least one failure.
328  /// - When a given Read, or some set of reads has completed - whether it was successful, cancelled,
329  /// or failed - call in_pBatchIoCallback for the corresponding transfer. Pass in the list of
330  /// AkAsyncIOTransferInfo objects to receive the callback, as well as a list of results for each transfer,
331  /// e.g. AK_Success or some other AKRESULT. Do not call in_pBatchIoCallback for transfers that were not
332  /// dispatched (as indicated by the corresponding value in io_pDispatchResults).
333  /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
334  /// device is notified through the callback. The array of in_pTransferItems will not be valid, though.
335  /// - File position passed in each BatchIoTransferItem::pTransferInfo 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 "pFileDesc->uSector * Block_Size + Stream_Position", where Block_Size is obtained
338  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
339  ///
340  /// \return
341  /// - AK_Success: All I/O requests were successfully dispatched.
342  /// in_pBatchIoCallback must be called for each read that completes.
343  /// - AK_Fail: At least one failure occurred when dispatching reads.
344  /// The values of io_pDispatchResults should indicate which operation failed to be dispatched.
345  virtual AKRESULT BatchRead(
346  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
347  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
348  AkBatchIOCallback in_pBatchIoCallback, ///< Callback to execute to handle completion of multiple items simultaneously
349  AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
350  ) = 0;
351 
352  /// Write multiple data to multiple files (asynchronous).
353  /// \remarks
354  /// - Queue up multiple write requests at once, using the provided array of in_pTransferItems. There will
355  /// be in_uNumTransfers number of items in the array.
356  /// - io_pDispatchResults will contain an in_uNumTransfers number of items in the array. Each item in
357  /// io_pDispatchResults should be set to AK_Success if the corresponding write was successfully dispatched,
358  /// and set to AK_Failure otherwise. As well, the return value should be a cumulative result of the
359  /// dispatches, where AK_Success indicates all requests were dispatched successfully, and
360  /// io_pDispatchResults will not be investigated, whereas AK_Fail indicates at least one failure.
361  /// - When a given write, or some set of writes has completed - whether it was successful, cancelled,
362  /// or failed - call in_pBatchIoCallback for the corresponding transfer. Pass in the list of
363  /// AkAsyncIOTransferInfo objects to receive the callback, as well as a list of results for each transfer,
364  /// e.g. AK_Success or some other AKRESULT. Do not call in_pBatchIoCallback for transfers that were not
365  /// dispatched (as indicated by the corresponding value in io_pDispatchResults).
366  /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
367  /// device is notified through the callback. The array of in_pTransferItems will not be valid, though.
368  /// - File position passed in each BatchIoTransferItem::pTransferInfo takes the offset of this file relative
369  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
370  /// device as "pFileDesc->uSector * Block_Size + Stream_Position", where Block_Size is obtained
371  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
372  ///
373  /// \return
374  /// - AK_Success: All I/O requests were successfully dispatched.
375  /// in_pBatchIoCallback must be called for each write that completes.
376  /// - AK_Fail: At least one failure occurred when dispatching writes.
377  /// The values of io_pDispatchResults should indicate which operation failed to be dispatched.
378  virtual AKRESULT BatchWrite(
379  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
380  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
381  AkBatchIOCallback in_pBatchIoCallback, ///< Callback to execute to handle completion of multiple items simultaneously
382  AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
383  ) = 0;
384 
385  /// Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed.
386  /// Cancellation is normal and happens regularly; for example, whenever a sound stops before the end
387  /// or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength
388  /// and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests
389  /// at the same time.
390  /// \remarks
391  /// - Cancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception.
392  /// The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged
393  /// by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled
394  /// transfers to be resolved.
395  /// - When calling the callback function of a cancelled transfer, pass it *AK_Success*. Passing AK_Fail
396  /// to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not
397  /// what you want.
398  /// - If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once.
399  /// Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if
400  /// you don't do anything special in Cancel(), leave it to true. This will reduce the amount of useless calls.
401  /// If you set it to false, Cancel() will be called again for each remaining pending transfer that need to be cancelled.
402  /// - If io_bCancelAllTransfersForThisFile is not set, Cancel() is only called for a subset of pending
403  /// 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.
404  /// \warning
405  /// - The calling thread holds the stream's lock. You may call the callback function directly from here
406  /// (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here
407  /// for another thread to call the callback function.
408  /// - Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue,
409  /// be careful not to run into a deadlock. Cancel() can be executed by any thread. Thus, if you need to lock your queue
410  /// in Cancel(), you must never hold this lock when calling back transfers, either from within Cancel() or from your
411  /// worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if
412  /// the transfer was found and dequeued. On the other hand, if you choose not to do anything in Cancel(), the lock only protects
413  /// your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the
414  /// stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
415  /// - A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook.
416  /// If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later
417  /// (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
418  virtual void BatchCancel(
419  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
420  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
421  bool** io_ppbCancelAllTransfersForThisFile ///< Flag for each transfer indicating whether all transfers should be cancelled for this file (see notes in function description).
422  ) = 0;
423  };
424 
425 
426  /// Interface for deferred low-level I/O transfers. Used by streaming devices created with the
427  /// AK_SCHEDULER_DEFERRED_LINED_UP flag.
428  /// This is an "adapter" interface to forward calls to IAkIOHookDeferredBatch, to maintain
429  /// compatibility with existing implementations, as well as provide a simpler interface for new
430  /// implementations.
431  /// This I/O transfer handshaking method is preferred when you want to hook I/O to your own
432  /// I/O streaming technology. You will receive up to AkDeviceSettings::uMaxConcurrentIO requests
433  /// at the same time. You may queue them into your own system, and even use the heuristics passed
434  /// down to this level for your convenience.
435  /// Note that the requests are always sent in the order that the Stream Manager considers to be
436  /// the most appropriate. You may receive less than AkDeviceSettings::uMaxConcurrentIO at any
437  /// given time. The number of concurrent transfers depends on the number of streams running in
438  /// the high-level streaming device, and on its target buffering length and granularity.
439  /// Your advantage at this level is to be aware of file placement, so you may try to re-order
440  /// requests in order to minimize seeking on disk.
441  /// Calls to Read()/Write() should return as soon as possible. You need to call
442  /// AkAsyncIOTransferInfo::pCallback as soon as a transfer is completed.
443  /// Cancel() is provided in order to inform you that the streaming device will flush this transfer
444  /// upon completion. You may implement it or not. In all cases, you must call the callback.
446  {
447  protected:
448  /// Virtual destructor on interface to avoid warnings.
449  virtual ~IAkIOHookDeferred(){}
450 
451  public:
452  /// Reads data from a file (asynchronous).
453  /// \remarks
454  /// - Queue up your read request with address, size and file position specified in io_transferInfo.
455  /// - When transfer is complete (whether it was successful, cancelled or failed), call
456  /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Read(), do not call
457  /// AkAsyncIOTransferInfo::pCallback.
458  /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
459  /// be changed by the Low-Level I/O.
460  /// - The reference to io_transferInfo will be valid until the high-level device is notified
461  /// through the callback.
462  /// - File position passed in io_transferInfo takes the offset of this file relative
463  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
464  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
465  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
466  /// \return
467  /// - AK_Success: An I/O request was successfully dispatched and is pending:
468  /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
469  /// - AK_Fail: An error occurred, no I/O request was dispatched
470  virtual AKRESULT Read(
471  AkFileDesc & in_fileDesc, ///< File descriptor.
472  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
473  AkAsyncIOTransferInfo & io_transferInfo ///< Asynchronous data transfer info.
474  ) = 0;
475 
476  /// Writes data to a file (asynchronous).
477  /// \remarks
478  /// - Queue up your write request with address, size and file position specified in io_transferInfo.
479  /// - When transfer is complete (whether it was successful, cancelled or failed), call
480  /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Write(), do not call
481  /// AkAsyncIOTransferInfo::pCallback.
482  /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
483  /// be changed by the Low-Level I/O.
484  /// - The reference to io_transferInfo will be valid until the high-level device is notified
485  /// through the callback.
486  /// - File position passed in io_transferInfo takes the offset of this file relative
487  /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
488  /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
489  /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
490  /// \return
491  /// - AK_Success: An I/O request was successfully processed and is pending:
492  /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
493  /// - AK_Fail: an error occured.
494  virtual AKRESULT Write(
495  AkFileDesc & in_fileDesc, ///< File descriptor.
496  const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
497  AkAsyncIOTransferInfo & io_transferInfo ///< Platform-specific asynchronous IO operation info.
498  ) = 0;
499 
500  /// Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed.
501  /// Cancellation is normal and happens regularly; for example, whenever a sound stops before the end
502  /// or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength
503  /// and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests
504  /// at the same time.
505  /// \remarks
506  /// - Cancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception.
507  /// The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged
508  /// by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled
509  /// transfers to be resolved.
510  /// - When calling the callback function of a cancelled transfer, pass it *AK_Success*. Passing AK_Fail
511  /// to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not
512  /// what you want.
513  /// - If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once.
514  /// Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if
515  /// you don't do anything special in Cancel(), leave it to true. This will reduce the amount of useless calls.
516  /// If you set it to false, Cancel() will be called again for each remaining pending transfer that need to be cancelled.
517  /// - If io_bCancelAllTransfersForThisFile is not set, Cancel() is only called for a subset of pending
518  /// 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.
519  /// \warning
520  /// - The calling thread holds the stream's lock. You may call the callback function directly from here
521  /// (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here
522  /// for another thread to call the callback function.
523  /// - Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue,
524  /// be careful not to run into a deadlock. Cancel() can be executed by any thread. Thus, if you need to lock your queue
525  /// in Cancel(), you must never hold this lock when calling back transfers, either from within Cancel() or from your
526  /// worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if
527  /// the transfer was found and dequeued. On the other hand, if you choose not to do anything in Cancel(), the lock only protects
528  /// your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the
529  /// stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
530  /// - A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook.
531  /// If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later
532  /// (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
533  virtual void Cancel(
534  AkFileDesc & in_fileDesc, ///< File descriptor.
535  AkAsyncIOTransferInfo & io_transferInfo, ///< Transfer info to cancel.
536  bool & io_bCancelAllTransfersForThisFile ///< Flag indicating whether all transfers should be cancelled for this file (see notes in function description).
537  ) = 0;
538 
539  /// The following functions each provide "stub" implementations of IAkHookDeferredIOBatch operations, so as to forward calls to
540  /// the existing single-transfer variants. The soundengine never calls IAkHookDeferred::Read et al, internally, and only
541  /// ever calls IAkIOHookDeferredBatch::BatchRead et al.
542  virtual AKRESULT BatchRead(
543  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
544  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
545  AkBatchIOCallback /*in_pBatchIoCallback*/,///< Callback to execute to handle completion of multiple items simultaneously
546  AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
547  )
548  {
549  AKRESULT cumulativeResult = AK_Success;
550  for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
551  {
552  BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
553  AKRESULT result = Read(*(ioTransferItem.pFileDesc), ioTransferItem.ioHeuristics, *(ioTransferItem.pTransferInfo));
554  io_pDispatchResults[i] = result;
555  cumulativeResult = result == AK_Success ? cumulativeResult : AK_Fail;
556  }
557  return cumulativeResult;
558  }
559 
560  virtual AKRESULT BatchWrite(
561  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
562  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
563  AkBatchIOCallback /*in_pBatchIoCallback*/,///< Callback to execute to handle completion of multiple items simultaneously
564  AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
565  )
566  {
567  AKRESULT cumulativeResult = AK_Success;
568  for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
569  {
570  BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
571  AKRESULT result = Write(*(ioTransferItem.pFileDesc), ioTransferItem.ioHeuristics, *(ioTransferItem.pTransferInfo));
572  io_pDispatchResults[i] = result;
573  cumulativeResult = result == AK_Success ? cumulativeResult : AK_Fail;
574  }
575  return cumulativeResult;
576  }
577  virtual void BatchCancel(
578  AkUInt32 in_uNumTransfers, ///< Number of transfers to process
579  BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
580  bool** io_ppbCancelAllTransfersForThisFile ///< Flag for each transfer indicating whether all transfers should be cancelled for this file (see notes in function description).
581  )
582  {
583  for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
584  {
585  BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
586  Cancel(*(ioTransferItem.pFileDesc), *(ioTransferItem.pTransferInfo), *(io_ppbCancelAllTransfersForThisFile[i]));
587  }
588  }
589 
590  };
591 
592  /// File location resolver interface. There is one and only one File Location Resolver that is
593  /// registered to the Stream Manager (using AK::StreamMgr::SetFileLocationResolver()). Its purpose
594  /// is to map a file name or ID to
595  /// 1) a streaming device / I/O hook;
596  /// 2) a valid file descriptor (AkFileDesc) usable by the I/O hook.
597  /// When your Low-Level I/O submodule uses a single device, you should create a standalone I/O
598  /// hook which implements one of the I/O hooks defined above (blocking or deferred), as well
599  /// as the File Location Resolver. You then register this object to the Stream Manager as the
600  /// File Location Resolver.
601  /// If you wish to create multiple devices, then you should have a separate object that implements
602  /// AK::StreamMgr::IAkFileLocationResolver and registers to the Stream Manager as such. This object
603  /// will be used to dispatch the file open request to the appropriate device. The strategy you will
604  /// use to select the correct device is up to you to implement. You may also implement a set of
605  /// hooks that delegate opening to the next device when they can't find the file requested
606  /// (like a chain of responsiblity pattern), although this will likely be less efficient.
608  {
609  protected:
610  /// Virtual destructor on interface to avoid warnings.
612 
613  public:
614 
615  /// Returns a file descriptor for a given file name (string).
616  /// Performs the operations needed to make the file descriptor usable by
617  /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
618  /// \return
619  /// - AK_Success: A valid file descriptor is returned
620  /// - AK_FileNotFound: File was not found.
621  /// - AK_Fail: File could not be open for any other reason.
622  /// \return
623  /// - A file descriptor, which contains
624  /// - an unique identifier to be used with functions of the low-level IO
625  /// interface.
626  /// - the total stream size in bytes.
627  /// - the offset from the beginning of the file (in blocks).
628  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
629  /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
630  /// \remarks
631  /// - The file descriptor is unique for each stream, and its address remains the same
632  /// throughout its lifetime. In other words, the value of &in_fileDesc inside Read() or
633  /// Close() is the same as &out_fileDesc in Open().
634  /// - Open() is always called first in the client thread.
635  /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
636  /// the File Location Resolver may choose whether it wants open it now, or later
637  /// from the streaming device's thread. If it wishes to open it now, then it must
638  /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
639  /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
640  /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
641  /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
642  /// this as a request for deferred file opening, and this function will called again
643  /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
644  /// - All members of out_fileDesc will be cleared upon first call to Open().
645  /// \warning
646  /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
647  /// set to true.
648  /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
649  /// The File Location Resolver should always choose to open files synchronously if it is
650  /// fast to do so.
651  /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
652  /// first call to Open(), in the client's thread, and is never called again.
653  /// \sa
654  /// - GetBlockSize()
655  /// - \ref streamingmanager_lowlevel_location
656  virtual AKRESULT Open(
657  const AkOSChar* in_pszFileName, ///< File name.
658  AkOpenMode in_eOpenMode, ///< Open mode.
659  AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
660  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.
661  AkFileDesc & io_fileDesc ///< Returned file descriptor.
662  ) = 0;
663 
664  /// Returns a file descriptor for a given file ID.
665  /// Performs the operations needed to make the file descriptor usable by
666  /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
667  /// \return
668  /// - AK_Success: A valid file descriptor is returned
669  /// - AK_FileNotFound: File was not found.
670  /// - AK_Fail: File could not be open for any other reason.
671  /// \return
672  /// - A file descriptor, which contains
673  /// - an unique identifier to be used with functions of the low-level IO
674  /// interface.
675  /// - the total stream size in bytes.
676  /// - the offset of the beginning of the file (in blocks).
677  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
678  /// - A file descriptor, that contains
679  /// - an unique identifier to be used with functions of the low-level IO
680  /// interface.
681  /// - the total stream size in bytes.
682  /// - the offset from the beginning of the file (in blocks).
683  /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
684  /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
685  /// \remarks
686  /// - Open() is always called first in the client thread.
687  /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
688  /// the File Location Resolver may choose whether it wants open it now, or later
689  /// from the streaming device's thread. If it wishes to open it now, then it must
690  /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
691  /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
692  /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
693  /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
694  /// this as a request for deferred file opening, and this function will called again
695  /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
696  /// - All members of out_fileDesc will be cleared upon first call to Open().
697  /// \warning
698  /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
699  /// set to true.
700  /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
701  /// The File Location Resolver should always choose to open files synchronously if it is
702  /// fast to do so.
703  /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
704  /// first call to Open(), in the client's thread, and is never called again.
705  /// - GetBlockSize()
706  /// - \ref streamingmanager_lowlevel_location
707  virtual AKRESULT Open(
708  AkFileID in_fileID, ///< File ID.
709  AkOpenMode in_eOpenMode, ///< Open mode.
710  AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
711  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.
712  AkFileDesc & io_fileDesc ///< Returned file descriptor.
713  ) = 0;
714  };
715 
716  /// \name Audiokinetic implementation-specific Stream Manager factory.
717  //@{
718  /// Stream Manager factory.
719  /// \remarks
720  /// - In order for the Stream Manager to work properly, you also need to create
721  /// at least one streaming device (and implement its I/O hook), and register the
722  /// File Location Resolver with AK::StreamMgr::SetFileLocationResolver().
723  /// - Use AK::StreamMgr::GetDefaultSettings(), then modify the settings you want,
724  /// then feed this function with them.
725  /// \sa
726  /// - AK::IAkStreamMgr
727  /// - AK::StreamMgr::SetFileLocationResolver()
728  /// - AK::StreamMgr::GetDefaultSettings()
729  AK_EXTERNAPIFUNC( IAkStreamMgr *, Create )(
730  const AkStreamMgrSettings & in_settings ///< Stream manager initialization settings.
731  );
732 
733  /// Get the default values for the Stream Manager's settings.
734  /// \sa
735  /// - AK::StreamMgr::Create()
736  /// - AkStreamMgrSettings
737  /// - \ref streamingmanager_settings
738  AK_EXTERNAPIFUNC( void, GetDefaultSettings )(
739  AkStreamMgrSettings & out_settings ///< Returned AkStreamMgrSettings structure with default values.
740  );
741 
742  /// Get the one and only File Location Resolver registered to the Stream Manager.
743  /// \sa
744  /// - AK::StreamMgr::IAkFileLocationResolver
745  /// - AK::StreamMgr::SetFileLocationResolver()
746  AK_EXTERNAPIFUNC( IAkFileLocationResolver *, GetFileLocationResolver )();
747 
748  /// Register the one and only File Location Resolver to the Stream Manager.
749  /// \sa
750  /// - AK::StreamMgr::IAkFileLocationResolver
751  AK_EXTERNAPIFUNC( void, SetFileLocationResolver )(
752  IAkFileLocationResolver * in_pFileLocationResolver ///< Interface to your File Location Resolver
753  );
754 
755  //@}
756 
757  /// \name Stream Manager: High-level I/O devices management.
758  //@{
759  /// Streaming device creation.
760  /// Creates a high-level device, with specific settings.
761  /// You need to provide the associated low-level I/O hook, implemented on your side.
762  /// \return The device ID. AK_INVALID_DEVICE_ID if there was an error and it could not be created.
763  /// \warning
764  /// - This function is not thread-safe.
765  /// - Use a blocking hook (IAkIOHookBlocking) with SCHEDULER_BLOCKING devices, and a
766  /// deferred hook (IAkIOHookDeferredBatch) with SCHEDULER_DEFERRED_LINED_UP devices (these flags are
767  /// specified in the device settings (AkDeviceSettings). The pointer to IAkLowLevelIOHook is
768  /// statically cast internally into one of these hooks. Implementing the wrong (or no) interface
769  /// will result into a crash.
770  /// \remarks
771  /// - You may use AK::StreamMgr::GetDefaultDeviceSettings() first to get default values for the
772  /// settings, change those you want, then feed the structure to this function.
773  /// - The returned device ID should be kept by the Low-Level IO, to assign it to file descriptors
774  /// in AK::StreamMgr::IAkFileLocationResolver::Open().
775  /// \sa
776  /// - AK::StreamMgr::IAkLowLevelIOHook
777  /// - AK::StreamMgr::GetDefaultDeviceSettings()
778  /// - \ref streamingmanager_settings
779  AK_EXTERNAPIFUNC( AkDeviceID, CreateDevice )(
780  const AkDeviceSettings & in_settings, ///< Device settings.
781  IAkLowLevelIOHook * in_pLowLevelHook ///< Associated low-level I/O hook. Pass either a IAkIOHookBlocking or a IAkIOHookDeferredBatch interface, consistent with the type of the scheduler.
782  );
783  /// Streaming device destruction.
784  /// \return AK_Success if the device was successfully destroyed.
785  /// \warning This function is not thread-safe. No stream should exist for that device when it is destroyed.
786  AK_EXTERNAPIFUNC( AKRESULT, DestroyDevice )(
787  AkDeviceID in_deviceID ///< Device ID of the device to destroy.
788  );
789 
790  /// Get the default values for the streaming device's settings. Recommended usage
791  /// is to call this function first, then pass the settings to AK::StreamMgr::CreateDevice().
792  /// \sa
793  /// - AK::StreamMgr::CreateDevice()
794  /// - AkDeviceSettings
795  /// - \ref streamingmanager_settings
796  AK_EXTERNAPIFUNC( void, GetDefaultDeviceSettings )(
797  AkDeviceSettings & out_settings ///< Returned AkDeviceSettings structure with default values.
798  );
799  //@}
800 
801  /// \name Language management.
802  //@{
803  /// Set the current language once and only once, here. The language name is stored in a static buffer
804  /// inside the Stream Manager. In order to resolve localized (language-specific) file location,
805  /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
806  /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
807  /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
808  /// Pass a valid null-terminated string, without a trailing slash or backslash. Empty strings are accepted.
809  /// You may register for language changes (see RegisterToLanguageChangeNotification()).
810  /// After changing the current language, all observers are notified.
811  /// \return AK_Success if successful (if language string has less than AK_MAX_LANGUAGE_NAME_SIZE characters). AK_Fail otherwise.
812  /// \warning Not multithread safe.
813  /// \sa
814  /// - AK::StreamMgr::GetCurrentLanguage()
815  /// - AK::StreamMgr::AddLanguageChangeObserver()
816  AK_EXTERNAPIFUNC( AKRESULT, SetCurrentLanguage )(
817  const AkOSChar * in_pszLanguageName ///< Language name.
818  );
819 
820  /// Get the current language. The language name is stored in a static buffer inside the Stream Manager,
821  /// with AK::StreamMgr::SetCurrentLanguage(). In order to resolve localized (language-specific) file location,
822  /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
823  /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
824  /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
825  /// \return Current language.
826  /// \sa AK::StreamMgr::SetCurrentLanguage()
827  AK_EXTERNAPIFUNC( const AkOSChar *, GetCurrentLanguage )();
828 
829  /// Definition of handlers for language change notifications.
830  /// Called after SetCurrentLanguage() is called.
831  /// \warning Do not call AddLanguageChangeObserver or SetCurrentLanguage from within your handler.
832  /// \warning Not multithread safe.
833  /// \sa
834  /// - AK::StreamMgr::SetCurrentLanguage()
835  /// - AK::StreamMgr::AddLanguageChangeObserver()
836  AK_CALLBACK( void, AkLanguageChangeHandler )(
837  const AkOSChar * const in_pLanguageName,///< New language name.
838  void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
839  );
840 
841  /// Register to language change notifications.
842  /// \return AK_Success if successful, AK_Fail otherwise (no memory or no cookie).
843  /// \warning Not multithread safe.
844  /// \sa
845  /// - AK::StreamMgr::SetCurrentLanguage()
846  /// - AK::StreamMgr::RemoveLanguageChangeObserver()
847  AK_EXTERNAPIFUNC( AKRESULT, AddLanguageChangeObserver )(
848  AkLanguageChangeHandler in_handler, ///< Callback function.
849  void * in_pCookie ///< Cookie, passed back to AkLanguageChangeHandler. Must set.
850  );
851 
852  /// Unregister to language change notifications. Use the cookie you have passed to
853  /// AddLanguageChangeObserver() to identify the observer.
854  /// \warning Not multithread safe.
855  /// \sa
856  /// - AK::StreamMgr::SetCurrentLanguage()
857  /// - AK::StreamMgr::AddLanguageChangeObserver()
858  AK_EXTERNAPIFUNC( void, RemoveLanguageChangeObserver )(
859  void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
860  );
861 
862  /// \name Stream Manager: Cache management.
863  //@{
864  /// Flush cache of all devices. This function has no effect for devices where
865  /// AkDeviceSettings::bUseStreamCache was set to false (no caching).
866  /// \sa
867  /// - \ref streamingmanager_settings
868  AK_EXTERNAPIFUNC( void, FlushAllCaches )();
869 
870  //@}
871  }
872 }
873 
874 #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.
virtual AKRESULT BatchWrite(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, AkBatchIOCallback in_pBatchIoCallback, AKRESULT *io_pDispatchResults)=0
AkUInt32 uIOMemoryAlignment
I/O memory alignment. It is passed directly to AK::MemoryMgr::Malign().
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 AkDeviceID __cdecl CreateDevice(const AkDeviceSettings &in_settings, IAkLowLevelIOHook *in_pLowLevelHook)
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.
virtual void BatchCancel(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, bool **io_ppbCancelAllTransfersForThisFile)=0
AkUInt32 uMaxConcurrentIO
Maximum number of transfers that can be sent simultaneously to the Low-Level I/O (applies to AK_SCHED...
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....
virtual ~IAkLowLevelIOHook()
Virtual destructor on interface to avoid warnings.
AkDeviceID deviceID
Device ID, obtained from CreateDevice()
AKSOUNDENGINE_API void __cdecl SetFileLocationResolver(IAkFileLocationResolver *in_pFileLocationResolver)
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 ePoolAttributes
Attributes for I/O memory. Here, specify the allocation type (AkMemType_Device, and so on)....
virtual ~IAkIOHookDeferredBatch()
Virtual destructor on interface to avoid warnings.
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 IAkFileLocationResolver *__cdecl GetFileLocationResolver()
AKSOUNDENGINE_API void __cdecl FlushAllCaches()
AkUInt32 uGranularity
I/O requests granularity (typical bytes/request).
virtual void BatchCancel(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, bool **io_ppbCancelAllTransfersForThisFile)
virtual AKRESULT BatchWrite(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, AkBatchIOCallback, AKRESULT *io_pDispatchResults)
virtual void GetDeviceDesc(AkDeviceDesc &out_deviceDesc)=0
AkUInt32 uSector
AKSOUNDENGINE_API void __cdecl GetDefaultDeviceSettings(AkDeviceSettings &out_settings)
AKSOUNDENGINE_API AKRESULT __cdecl SetCurrentLanguage(const AkOSChar *in_pszLanguageName)
AKSOUNDENGINE_API void __cdecl GetDefaultSettings(AkStreamMgrSettings &out_settings)
CAkFilePackage * pPackage
If this file is in a File Package, this will be the.
AKSOUNDENGINE_API AKRESULT __cdecl DestroyDevice(AkDeviceID in_deviceID)
File system flags for file descriptors mapping.
Definition: IAkStreamMgr.h:81
AKSOUNDENGINE_API void __cdecl RemoveLanguageChangeObserver(void *in_pCookie)
virtual AkUInt32 GetBlockSize(AkFileDesc &in_fileDesc)=0
AKSOUNDENGINE_API AKRESULT __cdecl AddLanguageChangeObserver(AkLanguageChangeHandler in_handler, void *in_pCookie)
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
const AKSOUNDENGINE_API AkOSChar *__cdecl GetCurrentLanguage()
virtual AKRESULT BatchRead(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, AkBatchIOCallback in_pBatchIoCallback, AKRESULT *io_pDispatchResults)=0
Device descriptor.
Definition: IAkStreamMgr.h:149
virtual AKRESULT Write(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, void *in_pData, AkIOTransferInfo &io_transferInfo)=0
virtual AKRESULT Read(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, void *out_pBuffer, AkIOTransferInfo &in_transferInfo)=0
AkUInt32 uCustomParamSize
Size of the custom parameter.
AKSOUNDENGINE_API IAkStreamMgr *__cdecl Create(const AkStreamMgrSettings &in_settings)
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 for I/O (for automatic streams). It is passed directly to AK::MemoryMgr::Malign(),...
AkFileHandle hFile
File handle/identifier.
AkInt64 iFileSize
File size in bytes.
virtual AKRESULT BatchRead(AkUInt32 in_uNumTransfers, BatchIoTransferItem *in_pTransferItems, AkBatchIOCallback, AKRESULT *io_pDispatchResults)
virtual AKRESULT Write(AkFileDesc &in_fileDesc, const AkIoHeuristics &in_heuristics, AkAsyncIOTransferInfo &io_transferInfo)=0
AkThreadProperties threadProperties
Scheduler thread properties.