123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- /*******************************************************************************
- The content of this file includes portions of the AUDIOKINETIC Wwise Technology
- released in source code form as part of the SDK installer package.
- Commercial License Usage
- Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
- may use this file in accordance with the end user license agreement provided
- with the software or, alternatively, in accordance with the terms contained in a
- written agreement between you and Audiokinetic Inc.
- Apache License Usage
- Alternatively, this file may be used under the Apache License, Version 2.0 (the
- "Apache License"); you may not use this file except in compliance with the
- Apache License. You may obtain a copy of the Apache License at
- http://www.apache.org/licenses/LICENSE-2.0.
- Unless required by applicable law or agreed to in writing, software distributed
- under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
- the specific language governing permissions and limitations under the License.
- Copyright (c) 2023 Audiokinetic Inc.
- *******************************************************************************/
- /// \file
- /// Audiokinetic's implementation-specific definitions and factory of
- /// overridable Stream Manager module.
- /// Contains the default Stream Manager's implementation-specific interfaces that altogether constitute
- /// the Low-Level I/O submodule. This submodule needs to be implemented by the game. All I/O requests
- /// generated by the Stream Manager end up to one of the I/O hooks defined herein.
- /// Read \ref streamingmanager_lowlevel to learn more about the Low-Level I/O.
- #ifndef _AK_STREAM_MGR_MODULE_H_
- #define _AK_STREAM_MGR_MODULE_H_
- #include <AK/SoundEngine/Common/IAkStreamMgr.h>
- #include <AK/Tools/Common/AkPlatformFuncs.h>
- class CAkFilePackage;
- /// \name Audiokinetic Stream Manager's implementation-specific definitions.
- //@{
- /// Stream Manager initialization settings.
- /// \sa
- /// - AK::IAkStreamMgr
- /// - AK::StreamMgr::Create()
- /// - \ref streamingmanager_settings
- struct AkStreamMgrSettings
- {
- };
- /// High-level IO devices initialization settings.
- /// \sa
- /// - AK::IAkStreamMgr
- /// - AK::StreamMgr::CreateDevice()
- /// - \ref streamingmanager_settings
- struct AkDeviceSettings
- {
- void * pIOMemory; ///< Pointer for I/O memory allocated by user.
- ///< Pass NULL if you want memory to be allocated via AK::MemoryMgr::Malign().
- ///< If specified, uIOMemorySize, uIOMemoryAlignment and ePoolAttributes are ignored.
- 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.
- AkUInt32 uIOMemoryAlignment; ///< I/O memory alignment. It is passed directly to AK::MemoryMgr::Malign().
- 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().
- AkUInt32 uGranularity; ///< I/O requests granularity (typical bytes/request).
- AkUInt32 uSchedulerTypeFlags; ///< Scheduler type flags.
- AkThreadProperties threadProperties; ///< Scheduler thread properties.
- 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.
- AkUInt32 uMaxConcurrentIO; ///< Maximum number of transfers that can be sent simultaneously to the Low-Level I/O.
- 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.
- AkUInt32 uMaxCachePinnedBytes; ///< Maximum number of bytes that can be "pinned" using AK::SoundEngine::PinEventInStreamCache() or AK::IAkStreamMgr::PinFileInCache()
- };
- /// \name Scheduler type flags.
- /// Requests to Low-Level IO are synchronous. The streaming device expects a blocking I/O hook at creation time (IAkIOHookBlocking interface, see CreateDevice()).
- /// Functions of this interface should return only when the transfer is complete.
- #define AK_SCHEDULER_BLOCKING (0x01)
- /// Requests to Low-Level IO are asynchronous, but posted one after the other, starting with streams that need data the most.
- /// The streaming device expects a deferred I/O hook at creation time (IAkIOHookDeferredBatch interface, see CreateDevice()).
- /// Up to AkDeviceSettings::uMaxConcurrentIO requests can be sent to the Low-Level I/O at the same time.
- #define AK_SCHEDULER_DEFERRED_LINED_UP (0x02)
- /// File descriptor. File identification for the low-level I/O.
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook
- struct AkFileDesc
- {
- AkInt64 iFileSize; ///< File size in bytes
- AkUInt64 uSector; ///< Start sector (the sector size is specified by the low-level I/O)
- ///< \sa
- ///< - AK::StreamMgr::IAkFileLocationResolver::Open()
- ///< - AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize()
- AkUInt32 uCustomParamSize; ///< Size of the custom parameter
- void * pCustomParam; ///< Custom parameter
- AkFileHandle hFile; ///< File handle/identifier
- AkDeviceID deviceID; ///< Device ID, obtained from CreateDevice() \sa AK::IAkStreamMgr::CreateDevice()
- CAkFilePackage* pPackage; ///< If this file is in a File Package, this will be the
- };
- /// Structure for synchronous transfers handshaking with the Low-Level I/O. Used with blocking I/O hooks.
- /// \sa AK::StreamMgr::IAkIOHookBlocking
- struct AkIOTransferInfo
- {
- AkUInt64 uFilePosition; ///< File offset where transfer should begin.
- AkUInt32 uBufferSize; ///< Size of the buffer in which the I/O hook can write to.
- AkUInt32 uRequestedSize; ///< Exact number of requested bytes for this transfer. Always equal to or smaller than uBufferSize.
- };
- struct AkAsyncIOTransferInfo;
- /// Callback function prototype definition used for asynchronous I/O transfers between the Stream Manager
- /// and the Low-Level IO. Used with deferred I/O hooks.
- /// Notes:
- /// - 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.
- /// - If the transfer was cancelled by the Stream Manager while it was in the Low-Level IO, you must return AK_Success, whether
- /// 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.
- /// \sa
- /// - AkAsyncIOTransferInfo
- /// - AK::StreamMgr::IAkIOHookDeferredBatch
- AK_CALLBACK( void, AkIOCallback )(
- AkAsyncIOTransferInfo * in_pTransferInfo, ///< Pointer to the AkAsyncIOTransferInfo structure that was passed to corresponding Read() or Write() call.
- AKRESULT in_eResult ///< Result of transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
- );
- /// Callback function prototype definition used for asynchronous I/O transfers between the Stream Manager
- /// and the Low-Level IO. Used with batch deferred I/O hooks.
- /// Notes:
- /// - in_peResult and in_ppTransferInfo must both contain in_uNumTransfers number of elements
- /// - 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.
- /// - 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
- /// 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.
- /// - 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
- /// each element of in_ppTransferInfo passed in only has the IOCallback fired on it one time.
- /// \sa
- /// - AkAsyncIOTransferInfo
- /// - AK::StreamMgr::IAkIOHookDeferredBatch
- AK_CALLBACK(void, AkBatchIOCallback)(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- AkAsyncIOTransferInfo** in_ppTransferInfo, ///< List of pointers to AkAsyncIOTransferInfo structures that were previously passed in to BatchRead() or BatchWrite()
- AKRESULT* in_peResult ///< Array of results of each transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
- );
- /// Structure for asynchronous transfers handshaking with the Low-Level I/O. Extends AkIOTransferInfo.
- /// \sa
- /// - AK::StreamMgr::IAkIOHookDeferredBatch
- /// - AkIOTransferInfo
- /// - AkAIOCallback
- struct AkAsyncIOTransferInfo : public AkIOTransferInfo
- {
- void * pBuffer; ///< Buffer for data transfer.
- AkIOCallback pCallback; ///< Callback function used to notify the high-level device when the transfer is complete.
- void * pCookie; ///< Reserved. The I/O device uses this cookie to retrieve the owner of the transfer.
- void * pUserData; ///< Custom user data.
- };
- /// Low-Level I/O requests heuristics.
- /// Used for asynchronous read requests.
- /// \sa
- /// - AK::StreamMgr::IAkIOHookBlocking::Read()
- /// - AK::StreamMgr::IAkIOHookBlocking::Write()
- /// - AK::StreamMgr::IAkIOHookDeferredBatch::Read()
- /// - AK::StreamMgr::IAkIOHookDeferredBatch::Write()
- struct AkIoHeuristics
- {
- AkReal32 fDeadline; ///< Operation deadline (ms).
- 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.
- };
- //@}
- namespace AK
- {
- /// Audiokinetic Stream Manager's implementation-specific interfaces of the Low-Level IO submodule.
- namespace StreamMgr
- {
- /// Base interface for Low-Level I/O hooks. Defines common methods across both types of hooks.
- class IAkLowLevelIOHook
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkLowLevelIOHook(){}
- public:
- /// Cleans up a file.
- /// \return AK_Success if the file was properly cleaned-up.
- virtual AKRESULT Close(
- AkFileDesc & in_fileDesc ///< File descriptor.
- ) = 0;
- /// Returns the block size for the file or its storage device.
- /// The block size is a constraint for clients
- /// of the Stream Manager: All reads, writes and position changes need to be a multiple of
- /// that size.
- /// \return
- /// The block size for a specific file or storage device.
- /// \remarks
- /// - Some files might be opened with flags that require I/O transfers to be a multiple
- /// of this size. The stream manager will query this function to resolve calls
- /// to IAk(Auto)Stream::GetBlockSize( ).
- /// - Also, AkFileDesc::uSector specifies a number of sectors in multiples of this value.
- /// - Files/IO devices that do not require byte alignment should return 1.
- /// - Whether file opening was deferred or not, GetBlockSize() is always called right
- /// after the first call to Open(), in the client's thread, and is never called again.
- /// \warning
- /// Returning 0 is not allowed and will likely make the Stream Manager crash.
- /// \sa
- /// - AK::StreamMgr::IAkFileLocationResolver::Open()
- /// - AK::StreamMgr::IAkIOHookBlocking::Read()
- /// - AK::StreamMgr::IAkIOHookBlocking::Write()
- /// - AK::StreamMgr::IAkIOHookDeferredBatch::Read()
- /// - AK::StreamMgr::IAkIOHookDeferredBatch::Write()
- virtual AkUInt32 GetBlockSize(
- AkFileDesc & in_fileDesc ///< File descriptor.
- ) = 0;
- /// Returns a description for the streaming device above this low-level hook.
- /// \remarks For profiling purposes only. The Release configuration of the
- /// Stream Manager never calls it.
- virtual void GetDeviceDesc(
- AkDeviceDesc & out_deviceDesc ///< Device description.
- ) = 0;
- /// Returns custom profiling data for the streaming device above this low-level hook.
- /// As opposed to GetDeviceDesc(), this is called at every monitoring frame.
- /// You may implement this function in order to display any value you find useful
- /// in the "Streaming Devices" tab of the Wwise profiler ("Custom Param" column).
- /// \remarks For profiling purposes only. The Release configuration of the
- /// Stream Manager never calls it.
- /// \return A 32-bit unsigned value to display in the Wwise profiler.
- virtual AkUInt32 GetDeviceData() = 0;
- };
- /// Interface for blocking low-level I/O transfers. Used by streaming devices created with the
- /// AK_SCHEDULER_BLOCKING flag.
- /// This is the simplest I/O hook. Calls to Read()/Write() must block until they are completed.
- /// The streaming device's I/O thread sends one transfer at a time.
- class IAkIOHookBlocking : public IAkLowLevelIOHook
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkIOHookBlocking(){}
- public:
- /// Reads data from a file (synchronous).
- /// Read data from the file described by in_fileDesc, in address out_pBuffer and with size and position
- /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
- /// \remarks
- /// File position passed in io_transferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- /// \return
- /// - AK_Success: transfer was successful and out_pBuffer is filled with data.
- /// - AK_Fail: an error occured.
- virtual AKRESULT Read(
- AkFileDesc & in_fileDesc, ///< File descriptor.
- const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
- void * out_pBuffer, ///< Buffer to be filled with data.
- AkIOTransferInfo & in_transferInfo ///< Synchronous data transfer info.
- ) = 0;
- /// Writes data to a file (synchronous).
- /// Write data to the file described by in_fileDesc, from address in_pData and with size and position
- /// passed within io_transferInfo. When transfer is complete, return with the proper return code.
- /// \remarks File position passed in io_transferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- /// \return
- /// - AK_Success: transfer was successful.
- /// - AK_Fail: an error occured.
- virtual AKRESULT Write(
- AkFileDesc & in_fileDesc, ///< File descriptor.
- const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
- void * in_pData, ///< Data to be written.
- AkIOTransferInfo & io_transferInfo ///< Synchronous data transfer info.
- ) = 0;
- };
- /// Interface for batched deferred low-level I/O transfers. Used by streaming devices created
- /// with the AK_SCHEDULER_DEFERRED_LINED_UP flag.
- /// This I/O transfer handshaking method is preferred when you want to hook I/O to your own
- /// I/O streaming technology, and you want to submit multiple I/O requests in one call, so as
- /// to allow for better opportunities for CPU and I/O performance.
- /// You may queue them into your own system, and even use the heuristics passed down to this
- /// level for your convenience. Note that the requests are always sent in the order that the
- /// Stream Manager considers to be the most appropriate. You may receive less than
- /// AkDeviceSettings::uMaxConcurrentIO at any given time. The number of concurrent transfers
- /// depends on the number of streams running in the high-level streaming device, and on its
- /// target buffering length and granularity. Your advantage at this level is to be aware of
- /// file placement, so you may try to re-order requests in order to minimize seeking on disk.
- /// Calls to BatchRead()/BatchWrite() should return as soon as possible. You need to call
- /// AkAsyncIOTransferInfo::pCallback for an individual item, or AkBatchIOCallback for a collection
- /// of items as soon as a transfer is completed.
- /// Cancel() is provided in order to inform you that the streaming device will flush this transfer
- /// upon completion. You may implement it or not. In all cases, you must call the callback.
- class IAkIOHookDeferredBatch : public IAkLowLevelIOHook
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkIOHookDeferredBatch() {}
- public:
- struct BatchIoTransferItem
- {
- AkFileDesc* pFileDesc;
- AkIoHeuristics ioHeuristics;
- AkAsyncIOTransferInfo* pTransferInfo;
- };
- /// Reads multiple data from multiple files (asynchronous).
- /// \remarks
- /// - Queue up multiple read requests at once, using the provided array of in_pTransferItems. There will
- /// be in_uNumTransfers number of items in the array.
- /// - io_pDispatchResults will contain an in_uNumTransfers number of items in the array. Each item in
- /// io_pDispatchResults should be set to AK_Success if the corresponding Read was successfully dispatched,
- /// and set to AK_Failure otherwise. As well, the return value should be a cumulative result of the
- /// dispatches, where AK_Success indicates all requests were dispatched successfully, and
- /// io_pDispatchResults will not be investigated, whereas AK_Fail indicates at least one failure.
- /// - When a given Read, or some set of reads has completed - whether it was successful, cancelled,
- /// or failed - call in_pBatchIoCallback for the corresponding transfer. Pass in the list of
- /// AkAsyncIOTransferInfo objects to receive the callback, as well as a list of results for each transfer,
- /// e.g. AK_Success or some other AKRESULT. Do not call in_pBatchIoCallback for transfers that were not
- /// dispatched (as indicated by the corresponding value in io_pDispatchResults).
- /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
- /// device is notified through the callback. The array of in_pTransferItems will not be valid, though.
- /// - File position passed in each BatchIoTransferItem::pTransferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "pFileDesc->uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- ///
- /// \return
- /// - AK_Success: All I/O requests were successfully dispatched.
- /// in_pBatchIoCallback must be called for each read that completes.
- /// - AK_Fail: At least one failure occurred when dispatching reads.
- /// The values of io_pDispatchResults should indicate which operation failed to be dispatched.
- virtual AKRESULT BatchRead(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- AkBatchIOCallback in_pBatchIoCallback, ///< Callback to execute to handle completion of multiple items simultaneously
- AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
- ) = 0;
- /// Write multiple data to multiple files (asynchronous).
- /// \remarks
- /// - Queue up multiple write requests at once, using the provided array of in_pTransferItems. There will
- /// be in_uNumTransfers number of items in the array.
- /// - io_pDispatchResults will contain an in_uNumTransfers number of items in the array. Each item in
- /// io_pDispatchResults should be set to AK_Success if the corresponding write was successfully dispatched,
- /// and set to AK_Failure otherwise. As well, the return value should be a cumulative result of the
- /// dispatches, where AK_Success indicates all requests were dispatched successfully, and
- /// io_pDispatchResults will not be investigated, whereas AK_Fail indicates at least one failure.
- /// - When a given write, or some set of writes has completed - whether it was successful, cancelled,
- /// or failed - call in_pBatchIoCallback for the corresponding transfer. Pass in the list of
- /// AkAsyncIOTransferInfo objects to receive the callback, as well as a list of results for each transfer,
- /// e.g. AK_Success or some other AKRESULT. Do not call in_pBatchIoCallback for transfers that were not
- /// dispatched (as indicated by the corresponding value in io_pDispatchResults).
- /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
- /// device is notified through the callback. The array of in_pTransferItems will not be valid, though.
- /// - File position passed in each BatchIoTransferItem::pTransferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "pFileDesc->uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- ///
- /// \return
- /// - AK_Success: All I/O requests were successfully dispatched.
- /// in_pBatchIoCallback must be called for each write that completes.
- /// - AK_Fail: At least one failure occurred when dispatching writes.
- /// The values of io_pDispatchResults should indicate which operation failed to be dispatched.
- virtual AKRESULT BatchWrite(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- AkBatchIOCallback in_pBatchIoCallback, ///< Callback to execute to handle completion of multiple items simultaneously
- AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
- ) = 0;
- /// Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed.
- /// Cancellation is normal and happens regularly; for example, whenever a sound stops before the end
- /// or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength
- /// and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests
- /// at the same time.
- /// \remarks
- /// - Cancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception.
- /// The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged
- /// by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled
- /// transfers to be resolved.
- /// - When calling the callback function of a cancelled transfer, pass it *AK_Success*. Passing AK_Fail
- /// to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not
- /// what you want.
- /// - If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once.
- /// Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if
- /// you don't do anything special in Cancel(), leave it to true. This will reduce the amount of useless calls.
- /// If you set it to false, Cancel() will be called again for each remaining pending transfer that need to be cancelled.
- /// - If io_bCancelAllTransfersForThisFile is not set, Cancel() is only called for a subset of pending
- /// 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.
- /// \warning
- /// - The calling thread holds the stream's lock. You may call the callback function directly from here
- /// (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here
- /// for another thread to call the callback function.
- /// - Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue,
- /// be careful not to run into a deadlock. Cancel() can be executed by any thread. Thus, if you need to lock your queue
- /// in Cancel(), you must never hold this lock when calling back transfers, either from within Cancel() or from your
- /// worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if
- /// the transfer was found and dequeued. On the other hand, if you choose not to do anything in Cancel(), the lock only protects
- /// your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the
- /// stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
- /// - A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook.
- /// If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later
- /// (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
- virtual void BatchCancel(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- bool** io_ppbCancelAllTransfersForThisFile ///< Flag for each transfer indicating whether all transfers should be cancelled for this file (see notes in function description).
- ) = 0;
- };
- /// Interface for deferred low-level I/O transfers. Used by streaming devices created with the
- /// AK_SCHEDULER_DEFERRED_LINED_UP flag.
- /// This is an "adapter" interface to forward calls to IAkIOHookDeferredBatch, to maintain
- /// compatibility with existing implementations, as well as provide a simpler interface for new
- /// implementations.
- /// This I/O transfer handshaking method is preferred when you want to hook I/O to your own
- /// I/O streaming technology. You will receive up to AkDeviceSettings::uMaxConcurrentIO requests
- /// at the same time. You may queue them into your own system, and even use the heuristics passed
- /// down to this level for your convenience.
- /// Note that the requests are always sent in the order that the Stream Manager considers to be
- /// the most appropriate. You may receive less than AkDeviceSettings::uMaxConcurrentIO at any
- /// given time. The number of concurrent transfers depends on the number of streams running in
- /// the high-level streaming device, and on its target buffering length and granularity.
- /// Your advantage at this level is to be aware of file placement, so you may try to re-order
- /// requests in order to minimize seeking on disk.
- /// Calls to Read()/Write() should return as soon as possible. You need to call
- /// AkAsyncIOTransferInfo::pCallback as soon as a transfer is completed.
- /// Cancel() is provided in order to inform you that the streaming device will flush this transfer
- /// upon completion. You may implement it or not. In all cases, you must call the callback.
- class IAkIOHookDeferred : public IAkIOHookDeferredBatch
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkIOHookDeferred(){}
- public:
- /// Reads data from a file (asynchronous).
- /// \remarks
- /// - Queue up your read request with address, size and file position specified in io_transferInfo.
- /// - When transfer is complete (whether it was successful, cancelled or failed), call
- /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Read(), do not call
- /// AkAsyncIOTransferInfo::pCallback.
- /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
- /// be changed by the Low-Level I/O.
- /// - The reference to io_transferInfo will be valid until the high-level device is notified
- /// through the callback.
- /// - File position passed in io_transferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- /// \return
- /// - AK_Success: An I/O request was successfully dispatched and is pending:
- /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
- /// - AK_Fail: An error occurred, no I/O request was dispatched
- virtual AKRESULT Read(
- AkFileDesc & in_fileDesc, ///< File descriptor.
- const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
- AkAsyncIOTransferInfo & io_transferInfo ///< Asynchronous data transfer info.
- ) = 0;
- /// Writes data to a file (asynchronous).
- /// \remarks
- /// - Queue up your write request with address, size and file position specified in io_transferInfo.
- /// - When transfer is complete (whether it was successful, cancelled or failed), call
- /// AkAsyncIOTransferInfo::pCallback. However, if you return AK_Fail() from Write(), do not call
- /// AkAsyncIOTransferInfo::pCallback.
- /// - AkAsyncIOTransferInfo::pCookie must be passed to the callback function as-is. It must not
- /// be changed by the Low-Level I/O.
- /// - The reference to io_transferInfo will be valid until the high-level device is notified
- /// through the callback.
- /// - File position passed in io_transferInfo takes the offset of this file relative
- /// to AkFileDesc::hFile (described with AkFileDesc::uSector). It is computed by the high-level
- /// device as "in_fileDesc.uSector * Block_Size + Stream_Position", where Block_Size is obtained
- /// via AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize().
- /// \return
- /// - AK_Success: An I/O request was successfully processed and is pending:
- /// AkAsyncIOTransferInfo::pCallback must be called when it completes.
- /// - AK_Fail: an error occured.
- virtual AKRESULT Write(
- AkFileDesc & in_fileDesc, ///< File descriptor.
- const AkIoHeuristics & in_heuristics, ///< Heuristics for this data transfer.
- AkAsyncIOTransferInfo & io_transferInfo ///< Platform-specific asynchronous IO operation info.
- ) = 0;
- /// Notifies that a transfer request is cancelled. It will be flushed by the streaming device when completed.
- /// Cancellation is normal and happens regularly; for example, whenever a sound stops before the end
- /// or stops looping. It happens even more frequently when buffering (AkDeviceSettings::fTargetAutoStmBufferLength
- /// and AkDeviceSettings::uGranularity) is large and when you low-level IO hook accepts many concurrent requests
- /// at the same time.
- /// \remarks
- /// - Cancel() simply informs the Low-Level I/O that a specific transfer will be flushed upon reception.
- /// The Low-Level I/O may use this information to stop this transfer right away, or not (it is internally tagged
- /// by the high-level device as cancelled). Nevertheless, the callback function MUST be called for cancelled
- /// transfers to be resolved.
- /// - When calling the callback function of a cancelled transfer, pass it *AK_Success*. Passing AK_Fail
- /// to AkAsyncIOTransfer::pCallback has the effect of killing the stream once and for all. This is not
- /// what you want.
- /// - If io_bCancelAllTransfersForThisFile is set, you may cancel all transfers for this file at once.
- /// Leave io_bCancelAllTransfersForThisFile to true if you don't want to be called again. For example, if
- /// you don't do anything special in Cancel(), leave it to true. This will reduce the amount of useless calls.
- /// If you set it to false, Cancel() will be called again for each remaining pending transfer that need to be cancelled.
- /// - If io_bCancelAllTransfersForThisFile is not set, Cancel() is only called for a subset of pending
- /// 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.
- /// \warning
- /// - The calling thread holds the stream's lock. You may call the callback function directly from here
- /// (if you can guarantee that the I/O buffer will not be accessed in the meantime), but you must not wait here
- /// for another thread to call the callback function.
- /// - Likewise, if you resolve transfers with your own thread and use a lock to protect your transfers queue,
- /// be careful not to run into a deadlock. Cancel() can be executed by any thread. Thus, if you need to lock your queue
- /// in Cancel(), you must never hold this lock when calling back transfers, either from within Cancel() or from your
- /// worker thread's routine. Lock your list, dequeue the transfer if you can, unlock, and call pCallback if and only if
- /// the transfer was found and dequeued. On the other hand, if you choose not to do anything in Cancel(), the lock only protects
- /// your list between Read()/Write() and your worker thread's routine, and since the device I/O thread does not hold the
- /// stream's lock while calling Read()/Write(), your worker thread may therefore hold it while calling back transfers.
- /// - A race condition exists when cancelling all transfers (io_bCancelAllTransfersForThisFile is true) directly from within this hook.
- /// If you handle the io_bCancelAllTransfersForThisFile == true case, you need to defer calling the completion callback to later
- /// (from your usual I/O completion thread, for example). This will be fixed in a future version of Wwise.
- virtual void Cancel(
- AkFileDesc & in_fileDesc, ///< File descriptor.
- AkAsyncIOTransferInfo & io_transferInfo, ///< Transfer info to cancel.
- bool & io_bCancelAllTransfersForThisFile ///< Flag indicating whether all transfers should be cancelled for this file (see notes in function description).
- ) = 0;
- /// The following functions each provide "stub" implementations of IAkHookDeferredIOBatch operations, so as to forward calls to
- /// the existing single-transfer variants. The soundengine never calls IAkHookDeferred::Read et al, internally, and only
- /// ever calls IAkIOHookDeferredBatch::BatchRead et al.
- virtual AKRESULT BatchRead(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- AkBatchIOCallback /*in_pBatchIoCallback*/,///< Callback to execute to handle completion of multiple items simultaneously
- AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
- )
- {
- AKRESULT cumulativeResult = AK_Success;
- for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
- {
- BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
- AKRESULT result = Read(*(ioTransferItem.pFileDesc), ioTransferItem.ioHeuristics, *(ioTransferItem.pTransferInfo));
- io_pDispatchResults[i] = result;
- cumulativeResult = result == AK_Success ? cumulativeResult : AK_Fail;
- }
- return cumulativeResult;
- }
- virtual AKRESULT BatchWrite(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- AkBatchIOCallback /*in_pBatchIoCallback*/,///< Callback to execute to handle completion of multiple items simultaneously
- AKRESULT* io_pDispatchResults ///< Output result codes to indicate if a transfer was successfully dispatched
- )
- {
- AKRESULT cumulativeResult = AK_Success;
- for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
- {
- BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
- AKRESULT result = Write(*(ioTransferItem.pFileDesc), ioTransferItem.ioHeuristics, *(ioTransferItem.pTransferInfo));
- io_pDispatchResults[i] = result;
- cumulativeResult = result == AK_Success ? cumulativeResult : AK_Fail;
- }
- return cumulativeResult;
- }
- virtual void BatchCancel(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems, ///< List of transfer items to process
- bool** io_ppbCancelAllTransfersForThisFile ///< Flag for each transfer indicating whether all transfers should be cancelled for this file (see notes in function description).
- )
- {
- for (AkUInt32 i = 0; i < in_uNumTransfers; ++i)
- {
- BatchIoTransferItem ioTransferItem = in_pTransferItems[i];
- Cancel(*(ioTransferItem.pFileDesc), *(ioTransferItem.pTransferInfo), *(io_ppbCancelAllTransfersForThisFile[i]));
- }
- }
- };
- /// File location resolver interface. There is one and only one File Location Resolver that is
- /// registered to the Stream Manager (using AK::StreamMgr::SetFileLocationResolver()). Its purpose
- /// is to map a file name or ID to
- /// 1) a streaming device / I/O hook;
- /// 2) a valid file descriptor (AkFileDesc) usable by the I/O hook.
- /// When your Low-Level I/O submodule uses a single device, you should create a standalone I/O
- /// hook which implements one of the I/O hooks defined above (blocking or deferred), as well
- /// as the File Location Resolver. You then register this object to the Stream Manager as the
- /// File Location Resolver.
- /// If you wish to create multiple devices, then you should have a separate object that implements
- /// AK::StreamMgr::IAkFileLocationResolver and registers to the Stream Manager as such. This object
- /// will be used to dispatch the file open request to the appropriate device. The strategy you will
- /// use to select the correct device is up to you to implement. You may also implement a set of
- /// hooks that delegate opening to the next device when they can't find the file requested
- /// (like a chain of responsiblity pattern), although this will likely be less efficient.
- class IAkFileLocationResolver
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkFileLocationResolver(){}
- public:
- /// Returns a file descriptor for a given file name (string).
- /// Performs the operations needed to make the file descriptor usable by
- /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
- /// \return
- /// - AK_Success: A valid file descriptor is returned
- /// - AK_FileNotFound: File was not found.
- /// - AK_Fail: File could not be open for any other reason.
- /// \return
- /// - A file descriptor, that contains
- /// - an unique identifier to be used with functions of the low-level IO
- /// interface.
- /// - the total stream size in bytes.
- /// - the offset from the beginning of the file (in blocks).
- /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
- /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
- /// \remarks
- /// - The file descriptor is unique for each stream, and its address remains the same
- /// throughout its lifetime. In other words, the value of &in_fileDesc inside Read() or
- /// Close() is the same as &out_fileDesc in Open().
- /// - Open() is always called first in the client thread.
- /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
- /// the File Location Resolver may choose whether it wants open it now, or later
- /// from the streaming device's thread. If it wishes to open it now, then it must
- /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
- /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
- /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
- /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
- /// this as a request for deferred file opening, and this function will called again
- /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
- /// - All members of out_fileDesc will be cleared upon first call to Open().
- /// \warning
- /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
- /// set to true.
- /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
- /// The File Location Resolver should always choose to open files synchronously if it is
- /// fast to do so.
- /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
- /// first call to Open(), in the client's thread, and is never called again.
- /// \sa
- /// - GetBlockSize()
- /// - \ref streamingmanager_lowlevel_location
- virtual AKRESULT Open(
- const AkOSChar* in_pszFileName, ///< File name.
- AkOpenMode in_eOpenMode, ///< Open mode.
- AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
- 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.
- AkFileDesc & io_fileDesc ///< Returned file descriptor.
- ) = 0;
- /// Returns a file descriptor for a given file ID.
- /// Performs the operations needed to make the file descriptor usable by
- /// the other methods of the interface (for e.g. ask the OS for a valid file handle).
- /// \return
- /// - AK_Success: A valid file descriptor is returned
- /// - AK_FileNotFound: File was not found.
- /// - AK_Fail: File could not be open for any other reason.
- /// \return
- /// - A file descriptor, that contains
- /// - an unique identifier to be used with functions of the low-level IO
- /// interface.
- /// - the total stream size in bytes.
- /// - the offset from the beginning of the file (in blocks).
- /// - a device ID, that was obtained through AK::StreamMgr::CreateDevice().
- /// - The updated io_bSyncOpen flag depending on the File Resolver's deferred opening policy.
- /// \remarks
- /// - Open() is always called first in the client thread.
- /// - If io_bSyncOpen is true, file opening must be executed now. If it is false,
- /// the File Location Resolver may choose whether it wants open it now, or later
- /// from the streaming device's thread. If it wishes to open it now, then it must
- /// set io_bSyncOpen to true. Otherwise, it needs to do the following: leave
- /// io_bSyncOpen to false, clear out_fileDesc::iFileSize and out_fileDesc::uSector,
- /// and set out_fileDesc::deviceID to the streaming device's ID that will handle
- /// this file. By returning io_bSyncOpen as false, the Stream Manager will interpret
- /// this as a request for deferred file opening, and this function will called again
- /// from the streaming device's thread (this time, with this io_bSyncOpen set to true).
- /// - All members of out_fileDesc will be cleared upon first call to Open().
- /// \warning
- /// - It is illegal to return io_bSyncOpen as false if Open() was called with io_bSyncOpen
- /// set to true.
- /// - Deferred file opening requires allocations in the Stream Manager's small object pool.
- /// The File Location Resolver should always choose to open files synchronously if it is
- /// fast to do so.
- /// - Whether opening is deferred or not, GetBlockSize() is always called right after the
- /// first call to Open(), in the client's thread, and is never called again.
- /// - GetBlockSize()
- /// - \ref streamingmanager_lowlevel_location
- virtual AKRESULT Open(
- AkFileID in_fileID, ///< File ID.
- AkOpenMode in_eOpenMode, ///< Open mode.
- AkFileSystemFlags * in_pFlags, ///< Special flags. Can pass NULL.
- 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.
- AkFileDesc & io_fileDesc ///< Returned file descriptor.
- ) = 0;
- /// <summary>
- /// 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.
- /// </summary>
- virtual AKRESULT OutputSearchedPaths(
- const AKRESULT& in_result, ///< Result of the open call
- const AkOSChar* in_pszFileName, ///< File name that was accessed
- AkFileSystemFlags* in_pFlags, ///< Special flags. Can be NULL.
- AkOpenMode in_eOpenMode, ///< File open mode (read, write, ...).
- AkOSChar* out_searchedPath, ///< Pre-allocated string buffer to be filled with all searched paths searched for the file.
- AkInt32 in_pathSize ///< The maximum size of the string
- ) { return AK_NotImplemented; };
- virtual AKRESULT OutputSearchedPaths(
- const AKRESULT& in_result, ///< Result of the open call
- const AkFileID in_fileID, ///< File ID that was accessed
- AkFileSystemFlags* in_pFlags, ///< Special flags. Can be NULL.
- AkOpenMode in_eOpenMode, ///< File open mode (read, write, ...).
- AkOSChar* out_searchedPath, ///< Pre-allocated string buffer to be filled with all searched paths searched for the file.
- AkInt32 in_pathSize ///< The maximum size of the string
- ) { return AK_NotImplemented; };
- };
- /// \name Audiokinetic implementation-specific Stream Manager factory.
- //@{
- /// Stream Manager factory.
- /// \remarks
- /// - In order for the Stream Manager to work properly, you also need to create
- /// at least one streaming device (and implement its I/O hook), and register the
- /// File Location Resolver with AK::StreamMgr::SetFileLocationResolver().
- /// - Use AK::StreamMgr::GetDefaultSettings(), then modify the settings you want,
- /// then feed this function with them.
- /// \sa
- /// - AK::IAkStreamMgr
- /// - AK::StreamMgr::SetFileLocationResolver()
- /// - AK::StreamMgr::GetDefaultSettings()
- AK_EXTERNAPIFUNC( IAkStreamMgr *, Create )(
- const AkStreamMgrSettings & in_settings ///< Stream manager initialization settings.
- );
- /// Get the default values for the Stream Manager's settings.
- /// \sa
- /// - AK::StreamMgr::Create()
- /// - AkStreamMgrSettings
- /// - \ref streamingmanager_settings
- AK_EXTERNAPIFUNC( void, GetDefaultSettings )(
- AkStreamMgrSettings & out_settings ///< Returned AkStreamMgrSettings structure with default values.
- );
- /// Get the one and only File Location Resolver registered to the Stream Manager.
- /// \sa
- /// - AK::StreamMgr::IAkFileLocationResolver
- /// - AK::StreamMgr::SetFileLocationResolver()
- AK_EXTERNAPIFUNC( IAkFileLocationResolver *, GetFileLocationResolver )();
- /// Register the one and only File Location Resolver to the Stream Manager.
- /// \sa
- /// - AK::StreamMgr::IAkFileLocationResolver
- AK_EXTERNAPIFUNC( void, SetFileLocationResolver )(
- IAkFileLocationResolver * in_pFileLocationResolver ///< Interface to your File Location Resolver
- );
- //@}
- /// \name Stream Manager: High-level I/O devices management.
- //@{
- /// Streaming device creation.
- /// Creates a high-level device, with specific settings.
- /// You need to provide the associated low-level I/O hook, implemented on your side.
- /// \return The device ID. AK_INVALID_DEVICE_ID if there was an error and it could not be created.
- /// \warning
- /// - This function is not thread-safe.
- /// - Use a blocking hook (IAkIOHookBlocking) with SCHEDULER_BLOCKING devices, and a
- /// deferred hook (IAkIOHookDeferredBatch) with SCHEDULER_DEFERRED_LINED_UP devices (these flags are
- /// specified in the device settings (AkDeviceSettings). The pointer to IAkLowLevelIOHook is
- /// statically cast internally into one of these hooks. Implementing the wrong (or no) interface
- /// will result into a crash.
- /// \remarks
- /// - You may use AK::StreamMgr::GetDefaultDeviceSettings() first to get default values for the
- /// settings, change those you want, then feed the structure to this function.
- /// - The returned device ID should be kept by the Low-Level IO, to assign it to file descriptors
- /// in AK::StreamMgr::IAkFileLocationResolver::Open().
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook
- /// - AK::StreamMgr::GetDefaultDeviceSettings()
- /// - \ref streamingmanager_settings
- AK_EXTERNAPIFUNC( AkDeviceID, CreateDevice )(
- const AkDeviceSettings & in_settings, ///< Device settings.
- IAkLowLevelIOHook * in_pLowLevelHook ///< Associated low-level I/O hook. Pass either a IAkIOHookBlocking or a IAkIOHookDeferredBatch interface, consistent with the type of the scheduler.
- );
- /// Streaming device destruction.
- /// \return AK_Success if the device was successfully destroyed.
- /// \warning This function is not thread-safe. No stream should exist for that device when it is destroyed.
- AK_EXTERNAPIFUNC( AKRESULT, DestroyDevice )(
- AkDeviceID in_deviceID ///< Device ID of the device to destroy.
- );
-
- /// Execute pending I/O operations on all created I/O devices.
- /// This should only be called in single-threaded environments where an I/O device cannot spawn a thread.
- /// \return AK_Success when called from an appropriate environment, AK_NotCompatible otherwise.
- /// \sa
- /// - AK::StreamMgr::CreateDevice()
- AK_EXTERNAPIFUNC( AKRESULT, PerformIO )();
- /// Get the default values for the streaming device's settings. Recommended usage
- /// is to call this function first, then pass the settings to AK::StreamMgr::CreateDevice().
- /// \sa
- /// - AK::StreamMgr::CreateDevice()
- /// - AkDeviceSettings
- /// - \ref streamingmanager_settings
- AK_EXTERNAPIFUNC( void, GetDefaultDeviceSettings )(
- AkDeviceSettings & out_settings ///< Returned AkDeviceSettings structure with default values.
- );
- //@}
- /// \name Language management.
- //@{
- /// Set the current language once and only once, here. The language name is stored in a static buffer
- /// inside the Stream Manager. In order to resolve localized (language-specific) file location,
- /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
- /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
- /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
- /// Pass a valid null-terminated string, without a trailing slash or backslash. Empty strings are accepted.
- /// You may register for language changes (see RegisterToLanguageChangeNotification()).
- /// After changing the current language, all observers are notified.
- /// \return AK_Success if successful (if language string has less than AK_MAX_LANGUAGE_NAME_SIZE characters). AK_Fail otherwise.
- /// \warning Not multithread safe.
- /// \sa
- /// - AK::StreamMgr::GetCurrentLanguage()
- /// - AK::StreamMgr::AddLanguageChangeObserver()
- AK_EXTERNAPIFUNC( AKRESULT, SetCurrentLanguage )(
- const AkOSChar * in_pszLanguageName ///< Language name.
- );
- /// Get the current language. The language name is stored in a static buffer inside the Stream Manager,
- /// with AK::StreamMgr::SetCurrentLanguage(). In order to resolve localized (language-specific) file location,
- /// AK::StreamMgr::IAkFileLocationResolver implementations query this string. They may use it to
- /// construct a file path (for e.g. SDK/samples/SoundEngine/Common/AkFileLocationBase.cpp), or to
- /// find a language-specific file within a look-up table (for e.g. SDK/samples/SoundEngine/Common/AkFilePackageLUT.cpp).
- /// \return Current language.
- /// \sa AK::StreamMgr::SetCurrentLanguage()
- AK_EXTERNAPIFUNC( const AkOSChar *, GetCurrentLanguage )();
- /// Definition of handlers for language change notifications.
- /// Called after SetCurrentLanguage() is called.
- /// \warning Do not call AddLanguageChangeObserver or SetCurrentLanguage from within your handler.
- /// \warning Not multithread safe.
- /// \sa
- /// - AK::StreamMgr::SetCurrentLanguage()
- /// - AK::StreamMgr::AddLanguageChangeObserver()
- AK_CALLBACK( void, AkLanguageChangeHandler )(
- const AkOSChar * const in_pLanguageName,///< New language name.
- void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
- );
- /// Register to language change notifications.
- /// \return AK_Success if successful, AK_Fail otherwise (no memory or no cookie).
- /// \warning Not multithread safe.
- /// \sa
- /// - AK::StreamMgr::SetCurrentLanguage()
- /// - AK::StreamMgr::RemoveLanguageChangeObserver()
- AK_EXTERNAPIFUNC( AKRESULT, AddLanguageChangeObserver )(
- AkLanguageChangeHandler in_handler, ///< Callback function.
- void * in_pCookie ///< Cookie, passed back to AkLanguageChangeHandler. Must set.
- );
- /// Unregister to language change notifications. Use the cookie you have passed to
- /// AddLanguageChangeObserver() to identify the observer.
- /// \warning Not multithread safe.
- /// \sa
- /// - AK::StreamMgr::SetCurrentLanguage()
- /// - AK::StreamMgr::AddLanguageChangeObserver()
- AK_EXTERNAPIFUNC( void, RemoveLanguageChangeObserver )(
- void * in_pCookie ///< Cookie that was passed to AddLanguageChangeObserver().
- );
- /// \name Stream Manager: Cache management.
- //@{
- /// Flush cache of all devices. This function has no effect for devices where
- /// AkDeviceSettings::bUseStreamCache was set to false (no caching).
- /// \sa
- /// - \ref streamingmanager_settings
- AK_EXTERNAPIFUNC( void, FlushAllCaches )();
-
- //@}
- }
- }
- #endif //_AK_STREAM_MGR_MODULE_H_
|