버전

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

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요