123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- /*******************************************************************************
- 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>
- /// \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).
- 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()
- };
- /// File descriptor. File identification for the low-level I/O.
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchOpen
- /// - AK::StreamMgr::IAkLowLevelIOHook::Close
- struct AkFileDesc
- {
- AkInt64 iFileSize = 0; ///< File size in bytes
- AkUInt64 uSector = 0; ///< Start sector (the sector size is specified by the low-level I/O)
- ///< \sa
- ///< - AK::StreamMgr::IAkFileLocationResolver::Open()
- ///< - AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize()
- AkFileHandle hFile = AkFileHandle(); ///< File handle/identifier
- AkDeviceID deviceID = AK_INVALID_DEVICE_ID; ///< Device ID, obtained from CreateDevice() \sa AK::IAkStreamMgr::CreateDevice()
- };
- /// Structure for synchronous transfers handshaking with the Low-Level I/O. Used with blocking I/O hooks.
- /// \sa AK::StreamMgr::IAkLowLevelIOHook
- 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.
- /// 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::IAkLowLevelIOHook
- 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).
- );
- /// Structure for asynchronous transfers handshaking with the Low-Level I/O. Extends AkIOTransferInfo.
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook
- /// - 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.
- };
- struct AkAsyncFileOpenData;
- /// Callback signature for the notification of completion of the asynchronous Open operation.
- /// \sa
- /// - AkAsyncFileOpenData
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchOpen
- AK_CALLBACK(void, AkFileOpenCallback)(
- AkAsyncFileOpenData * in_pOpenInfo, ///< Pointer to the AkAsyncFileOpenData structure that was passed to corresponding Open().
- AKRESULT in_eResult ///< Result of transfer: AK_Success or AK_Fail (streams waiting for this transfer become invalid).
- );
- /// Structure used by Low Level IO Hooks (IAkLowLevelIOHook) to pass and retreive information on files to be opened by the IO hook.
- /// Please refer to AK::StreamMgr::IAkLowLevelIOHook::BatchOpen for more information about the sementics of the Open operation.
- /// \sa
- /// - AkFileOpenData
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchOpen
- struct AkAsyncFileOpenData : public AkFileOpenData
- {
- ~AkAsyncFileOpenData();
- AkAsyncFileOpenData(const AkFileOpenData& in_copy)
- : pCallback(NULL)
- , pCookie(NULL)
- , pFileDesc(NULL)
- , pCustomData(NULL)
- , pszStreamName(NULL)
- {
- *(AkFileOpenData*)this = in_copy;
- }
- AkAsyncFileOpenData(const AkAsyncFileOpenData& in_copy)
- : pCallback(in_copy.pCallback)
- , pCookie(in_copy.pCookie)
- , pFileDesc(in_copy.pFileDesc)
- , pCustomData(NULL)
- , pszStreamName(NULL)
- {
- *(AkFileOpenData*)this = in_copy;
- }
- AkAsyncFileOpenData()
- : AkFileOpenData()
- , pCallback(NULL)
- , pCookie(NULL)
- , pFileDesc(NULL)
- , pCustomData(NULL)
- , pszStreamName(NULL)
- {}
-
- AkAsyncFileOpenData(const AkOSChar* in_pszFileName, AkOpenMode in_eOpenMode = AK_OpenModeRead, AkFileSystemFlags* in_pFlags = NULL)
- :AkFileOpenData(in_pszFileName, in_eOpenMode, in_pFlags)
- , pCallback(NULL)
- , pCookie(NULL)
- , pFileDesc(NULL)
- , pCustomData(NULL)
- , pszStreamName(NULL)
- {}
- AkAsyncFileOpenData(AkFileID in_idFile, AkOpenMode in_eOpenMode = AK_OpenModeRead, AkFileSystemFlags* in_pFlags = NULL)
- :AkFileOpenData(in_idFile, in_eOpenMode, in_pFlags)
- , pCallback(NULL)
- , pCookie(NULL)
- , pFileDesc(NULL)
- , pCustomData(NULL)
- , pszStreamName(NULL)
- {}
- ///< Functions used to manage optional stream name. The name will be used when sending stream information to the Wwise profiler.
- AKRESULT SetStreamName(const AkOSChar* in_pszStreamName);
- const AkOSChar* GetStreamName() const { return pszStreamName; }
- AkFileOpenCallback pCallback; ///< Callback function used to notify the high-level device when Open is done
- void* pCookie; ///< Reserved. Pass this unchanged to the callback function. The I/O device uses this cookie to retrieve the owner of the transfer.
- AkFileDesc* pFileDesc; ///< File Descriptor to fill once the Open operation is complete.
- void* pCustomData; ///< Convienience pointer for the IO hook implementer. Useful for additional data used in asynchronous implementations, for example.
- private:
- AkOSChar* pszStreamName; ///< Display name. If provided, this will be used to set the stream name, which is used for the profiler. This struct is not responsible for the memory.
- };
- /// Low-Level I/O requests heuristics.
- /// Used for asynchronous read requests.
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchRead()
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchWrite()
- 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
- {
- /// Interface for batched deferred low-level I/O transfers.
- /// 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.
- /// All operations in this interface will be happening in the device's own thread, separate
- /// from the main audio thread. Also, it is assumed that all operations are asynchronous although
- /// immediate resolution is also supported.
- /// 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 all individual items in a transfer batch.
- /// 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 IAkLowLevelIOHook
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkLowLevelIOHook(){}
- public:
- /// Closes a file.
- /// The file descriptor should be deleted during this call.
- /// No other module should have a reference to it at this point.
- /// \return AK_Success if the file was properly cleaned-up.
- virtual AKRESULT Close(
- AkFileDesc * in_pFileDesc ///< 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::IAkLowLevelIOHook::BatchOpen()
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchRead()
- /// - AK::StreamMgr::IAkLowLevelIOHook::BatchWrite()
- 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;
- struct BatchIoTransferItem
- {
- AkFileDesc* pFileDesc;
- AkIoHeuristics ioHeuristics;
- AkAsyncIOTransferInfo* pTransferInfo;
- };
- /// Request to open multiple files (asynchronous).
- /// \remarks
- /// - The pCallback within each AkAsyncFileOpenData must be called when completed.
- /// - It is possible to mix synchronous and asynchronous file opens, as long as all pCallbacks are eventually called.
- /// - When implementing this function, make sure to process all items even if one fails to be dispatched or to open.
- /// - Pointers in in_ppItems will stay valid until pCallback is called to signal the operation result.
- virtual void BatchOpen(
- AkUInt32 in_uNumFiles, ///< Number of transfers to process
- AkAsyncFileOpenData** in_ppItems ///< List of files to open. See remarks above.
- ) = 0;
- /// 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.
- /// - The pCallback within each BatchIoTransferItem::pTransferInfo must be called when completed.
- /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
- /// device is notified through the callback. However, the array of in_pTransferItems will not be valid.
- /// - 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().
- virtual void BatchRead(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems ///< List of transfer items to process
- ) = 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.
- /// - The pCallback within each BatchIoTransferItem::pTransferInfo must be called when completed.
- /// - The pointer to each BatchIoTransferItem::pTransferInfo will be valid until the high-level
- /// device is notified through the callback. However, the array of in_pTransferItems will not be valid.
- /// - 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().
- virtual void BatchWrite(
- AkUInt32 in_uNumTransfers, ///< Number of transfers to process
- BatchIoTransferItem* in_pTransferItems ///< List of transfer items to process
- ) = 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
- /// - BatchCancel() is an optional functionality that can be implemented as a no-op.
- /// - BatchCancel() 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 BatchCancel(), leave it to true. This will reduce the amount of useless calls.
- /// If you set it to false, BatchCancel() will be called again for each remaining pending transfer that need to be cancelled.
- /// - If io_bCancelAllTransfersForThisFile is not set, BatchCancel() is only called for a subset of pending
- /// transfers for this file. You must not set it to true, as BatchCancel() 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. BatchCancel() can be executed by any thread. Thus, if you need to lock your queue
- /// in BatchCancel(), you must never hold this lock when calling back transfers, either from within BatchCancel() 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 BatchCancel(), 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;
- /// This function is called to provide information when file related errors occur. The base paths known by this IO hook should be returned in out_searchedPath.
- virtual AKRESULT OutputSearchedPaths(
- AKRESULT in_result, ///< Result of the open call
- const AkFileOpenData& in_FileOpen, ///< File name and flags passed to the Open call.
- 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; };
- };
- /// 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 resolve a file name or ID to a streaming device (I/O hook) that can handle the file.
- /// 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, 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.
- /// There is a built-in mechanism of chaining devices through GetNextPreferredDevice().
- /// If a device can't open a file GetNextPreferredDevice will be called again to get the next
- /// device to check.
- class IAkFileLocationResolver
- {
- protected:
- /// Virtual destructor on interface to avoid warnings.
- virtual ~IAkFileLocationResolver(){}
- public:
- /// Determines which device to use to open a file.
- /// If your File Resolver only handles one device, return AK_NotImplemented and the StreamMgr will use the only device configured.
- /// If it handles multiple devices, you can base the decision on where to get the file on any kind of heuristic:
- /// file extension, file name, access rights, CodecID, etc.
- /// The order in which devices are searched is left to the implementer.
- /// This function will always be called first with io_idDevice = AK_INVALID_DEVICE_ID.
- /// \return
- /// - AK_Success if there is a device to delegate the Open() call to. io_idDevice should be set to the proper AkDeviceID (as returned by AK::StreamMgr::CreateDevice).
- /// - AK_FileNotFound if all devices have been exhausted.
- /// - AK_NotImplemented if there is only one device in the system and file resolution is trivial.
- /// \remark
- /// This can be called from multiple threads.
- /// Note that there is a
- virtual AKRESULT GetNextPreferredDevice(
- AkAsyncFileOpenData& in_FileOpen, ///< File name and flags passed to the Open call.
- AkDeviceID& io_idDevice ///< In: last device used. Out: next device to use to open the file
- )
- { 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.
- /// \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::IAkLowLevelIOHook::BatchOpen().
- /// \return
- /// - AK_Success: Device was added to the system properly
- /// - AK_InsufficientMemory: Not enough memory to complete the operation
- /// - AK_InvalidParameter: One of the settings in AkDeviceSettings is out of range. Check asserts or debug console.
- /// \sa
- /// - AK::StreamMgr::IAkLowLevelIOHook
- /// - AK::StreamMgr::GetDefaultDeviceSettings()
- /// - \ref streamingmanager_settings
- AK_EXTERNAPIFUNC( AKRESULT, CreateDevice )(
- const AkDeviceSettings & in_settings, ///< Device settings.
- IAkLowLevelIOHook * in_pLowLevelHook, ///< Associated low-level I/O hook. Pass either a IAkLowLevelIOHook interface, consistent with the type of the scheduler.
- AkDeviceID& out_idDevice ///< Assigned unique device id to use in all other functions of this interface.
- );
- /// 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_
|