/******************************************************************************* 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 /// Defines the API of Audiokinetic's I/O streaming solution. #ifndef _IAK_STREAM_MGR_H_ #define _IAK_STREAM_MGR_H_ #include //----------------------------------------------------------------------------- // Defines. //----------------------------------------------------------------------------- /// \name Profiling string lengths. //@{ #define AK_MONITOR_STREAMNAME_MAXLENGTH (64) #define AK_MONITOR_DEVICENAME_MAXLENGTH (16) //@} //----------------------------------------------------------------------------- // Enums. //----------------------------------------------------------------------------- /// Stream status. enum AkStmStatus { AK_StmStatusIdle = 0, ///< The stream is idle AK_StmStatusCompleted = 1, ///< Operation completed / Automatic stream reached end AK_StmStatusPending = 2, ///< Operation pending / The stream is waiting for I/O AK_StmStatusCancelled = 3, ///< Operation cancelled AK_StmStatusError = 4 ///< The low-level I/O reported an error }; /// Move method for position change. /// \sa /// - AK::IAkStdStream::SetPosition() /// - AK::IAkAutoStream::SetPosition() enum AkMoveMethod { AK_MoveBegin = 0, ///< Move offset from the start of the stream AK_MoveCurrent = 1, ///< Move offset from the current stream position AK_MoveEnd = 2 ///< Move offset from the end of the stream }; /// File open mode. enum AkOpenMode { AK_OpenModeRead = 0, ///< Read-only access AK_OpenModeWrite = 1, ///< Write-only access (opens the file if it already exists) AK_OpenModeWriteOvrwr = 2, ///< Write-only access (deletes the file if it already exists) AK_OpenModeReadWrite = 3 ///< Read and write access }; /// File system flags for file descriptors mapping. struct AkFileSystemFlags { AkFileSystemFlags() : uCompanyID(0) , uCodecID(0) , uCustomParamSize(0) , pCustomParam(0) , bIsLanguageSpecific(false) , bIsAutomaticStream(false) , uCacheID(AK_INVALID_FILE_ID) , uNumBytesPrefetch(0) , uDirectoryHash(AK_INVALID_UNIQUE_ID) {} AkFileSystemFlags( AkUInt32 in_uCompanyID, AkUInt32 in_uCodecID, AkUInt32 in_uCustomParamSize, void * in_pCustomParam, bool in_bIsLanguageSpecific, AkFileID in_uCacheID ) : uCompanyID( in_uCompanyID ) , uCodecID( in_uCodecID ) , uCustomParamSize( in_uCustomParamSize ) , pCustomParam( in_pCustomParam ) , bIsLanguageSpecific( in_bIsLanguageSpecific ) , uCacheID( in_uCacheID ) , uNumBytesPrefetch( 0 ) , uDirectoryHash( AK_INVALID_UNIQUE_ID ) {} AkUInt32 uCompanyID; ///< Company ID (Wwise uses AKCOMPANYID_AUDIOKINETIC, defined in AkTypes.h, for soundbanks and standard streaming files, and AKCOMPANYID_AUDIOKINETIC_EXTERNAL for streaming external sources). AkUInt32 uCodecID; ///< File/codec type ID (defined in AkTypes.h) AkUInt32 uCustomParamSize; ///< Size of the custom parameter void * pCustomParam; ///< Custom parameter bool bIsLanguageSpecific;///< True when the file location depends on language bool bIsAutomaticStream; ///< True when the file is opened to be used as an automatic stream. Note that you don't need to set it. ///< If you pass an AkFileSystemFlags to IAkStreamMgr CreateStd|Auto(), it will be set internally to the correct value. AkFileID uCacheID; ///< Cache ID for caching system used by automatic streams. The user is responsible for guaranteeing unicity of IDs. ///< When set, it supersedes the file ID passed to AK::IAkStreamMgr::CreateAuto() (ID version). Caching is optional and depends on the implementation. AkUInt32 uNumBytesPrefetch; ///< Indicates the number of bytes from the beginning of the file that should be streamed into cache via a caching stream. This field is only relevant when opening caching streams via ///< AK::IAkStreamMgr::PinFileInCache() and AK::SoundEngine::PinEventInStreamCache(). When using AK::SoundEngine::PinEventInStreamCache(), ///< it is initialized to the prefetch size stored in the sound bank, but may be changed by the file location resolver, or set to 0 to cancel caching. AkUInt32 uDirectoryHash; ///< If the implementation uses a hashed directory structure, this is the hash value that should be employed for determining the directory structure }; /// Stream information. /// \sa /// - AK::IAkStdStream::GetInfo() /// - AK::IAkAutoStream::GetInfo() struct AkStreamInfo { AkDeviceID deviceID; ///< Device ID const AkOSChar * pszName; ///< User-defined stream name (specified through AK::IAkStdStream::SetStreamName() or AK::IAkAutoStream::SetStreamName()) AkUInt64 uSize; ///< Total stream/file size in bytes bool bIsOpen; ///< True when the file is open (implementations may defer file opening) bool bIsLanguageSpecific;///< True when the file was found in a language specific location }; /// Automatic streams heuristics. struct AkAutoStmHeuristics { AkReal32 fThroughput; ///< Average throughput in bytes/ms AkUInt32 uLoopStart; ///< Set to the start of loop (byte offset from the beginning of the stream) for streams that loop, 0 otherwise AkUInt32 uLoopEnd; ///< Set to the end of loop (byte offset from the beginning of the stream) for streams that loop, 0 otherwise AkUInt8 uMinNumBuffers; ///< Minimum number of buffers if you plan to own more than one buffer at a time, 0 or 1 otherwise ///< \remarks You should always release buffers as fast as possible, therefore this heuristic should be used only when ///< dealing with special contraints, like drivers or hardware that require more than one buffer at a time.\n ///< Also, this is only a heuristic: it does not guarantee that data will be ready when calling AK::IAkAutoStream::GetBuffer(). AkPriority priority; ///< The stream priority. it should be between AK_MIN_PRIORITY and AK_MAX_PRIORITY (included). }; /// Automatic streams buffer settings/constraints. struct AkAutoStmBufSettings { AkUInt32 uBufferSize; ///< Hard user constraint: When non-zero, forces the I/O buffer to be of size uBufferSize ///< (overriding the device's granularity). ///< Otherwise, the size is determined by the device's granularity. AkUInt32 uMinBufferSize; ///< Soft user constraint: When non-zero, specifies a minimum buffer size ///< \remarks Ignored if uBufferSize is specified. AkUInt32 uBlockSize; ///< Hard user constraint: When non-zero, buffer size will be a multiple of that number, and returned addresses will always be aligned on multiples of this value. }; /// \name Profiling structures. //@{ #pragma pack(push, 4) /// Device descriptor. struct AkDeviceDesc { AkDeviceID deviceID; ///< Device ID bool bCanWrite; ///< Specifies whether or not the device is writable bool bCanRead; ///< Specifies whether or not the device is readable AkUtf16 szDeviceName[AK_MONITOR_DEVICENAME_MAXLENGTH]; ///< Device name AkUInt32 uStringSize; ///< Device name string's size (number of characters) }; /// Device descriptor. struct AkDeviceData { AkDeviceID deviceID; ///< Device ID AkUInt32 uMemSize; ///< IO memory pool size AkUInt32 uMemUsed; ///< IO memory pool used AkUInt32 uAllocs; ///< Cumulative number of allocations AkUInt32 uFrees; ///< Cumulative number of deallocations AkUInt32 uPeakRefdMemUsed; ///< Memory peak since monitoring started AkUInt32 uUnreferencedCachedBytes; ///< IO memory that is cached but is not currently used for active streams. AkUInt32 uGranularity; ///< IO memory pool block size AkUInt32 uNumActiveStreams; ///< Number of streams that have been active in the previous frame AkUInt32 uTotalBytesTransferred; ///< Number of bytes transferred, including cached transfers AkUInt32 uLowLevelBytesTransferred; ///< Number of bytes transferred exclusively via low-level AkReal32 fAvgCacheEfficiency; ///< Total bytes from cache as a percentage of total bytes. AkUInt32 uNumLowLevelRequestsCompleted; ///< Number of low-level transfers that have completed in the previous monitoring frame AkUInt32 uNumLowLevelRequestsCancelled; ///< Number of low-level transfers that were cancelled in the previous monitoring frame AkUInt32 uNumLowLevelRequestsPending; ///< Number of low-level transfers that are currently pending AkUInt32 uCustomParam; ///< Custom number queried from low-level IO. AkUInt32 uCachePinnedBytes; ///< Number of bytes that can be pinned into cache. }; /// Stream general information. struct AkStreamRecord { AkUInt32 uStreamID; ///< Unique stream identifier AkDeviceID deviceID; ///< Device ID AkUtf16 szStreamName[AK_MONITOR_STREAMNAME_MAXLENGTH]; ///< Stream name AkUInt32 uStringSize; ///< Stream name string's size (number of characters) AkUInt64 uFileSize; ///< File size bool bIsAutoStream; ///< True for auto streams bool bIsCachingStream; ///< True for caching streams }; /// Stream statistics. struct AkStreamData { AkUInt32 uStreamID; ///< Unique stream identifier // Status (replace) AkUInt32 uPriority; ///< Stream priority AkUInt64 uFilePosition; ///< Current position AkUInt32 uTargetBufferingSize; ///< Total stream buffer size (specific to IAkAutoStream) AkUInt32 uVirtualBufferingSize; ///< Size of available data including requested data (specific to IAkAutoStream) AkUInt32 uBufferedSize; ///< Size of available data (specific to IAkAutoStream) AkUInt32 uNumBytesTransfered; ///< Transfered amount since last query (Accumulate/Reset) AkUInt32 uNumBytesTransferedLowLevel;///< Transfered amount (from low-level IO only) since last query (Accumulate/Reset) AkUInt32 uMemoryReferenced; ///< Amount of streaming memory referenced by this stream AkReal32 fEstimatedThroughput; ///< Estimated throughput heuristic bool bActive; ///< True if this stream has been active (that is, was ready for I/O or had at least one pending I/O transfer, uncached or not) in the previous frame }; /// Contains parameters for the IAkFileLocationResolver::Open() call and related functions. /// Files can be designated with a file name or a file ID. Only one of the two members should be valid. /// \note pszFileName is stored on the stack and will be valid only through the function call. struct AkFileOpenData { AkFileOpenData() : pszFileName(NULL) , fileID(AK_INVALID_FILE_ID) , pFlags(NULL) , eOpenMode(AK_OpenModeRead) {} AkFileOpenData(const AkOSChar* in_pszFileName, AkOpenMode in_eOpenMode = AK_OpenModeRead, AkFileSystemFlags* in_pFlags = NULL) : pszFileName(in_pszFileName) , fileID(AK_INVALID_FILE_ID) , pFlags(in_pFlags) , eOpenMode(in_eOpenMode) {} AkFileOpenData(AkFileID in_idFile, AkOpenMode in_eOpenMode = AK_OpenModeRead, AkFileSystemFlags* in_pFlags = NULL) : pszFileName(NULL) , fileID(in_idFile) , pFlags(in_pFlags) , eOpenMode(in_eOpenMode) {} AkFileOpenData(const AkOSChar* in_pszFileName, AkFileSystemFlags* in_pFlags) : pszFileName(in_pszFileName) , fileID(AK_INVALID_FILE_ID) , pFlags(in_pFlags) , eOpenMode(AK_OpenModeRead) {} AkFileOpenData(AkFileID in_idFile, AkFileSystemFlags* in_pFlags) : pszFileName(NULL) , fileID(in_idFile) , pFlags(in_pFlags) , eOpenMode(AK_OpenModeRead) {} bool IsValid() const { return (pszFileName != NULL) != (fileID != AK_INVALID_FILE_ID); //Only one of pszFileName and fileID should be set. } const AkOSChar* pszFileName; ///< File name. Only one of pszFileName or fileID should be valid (pszFileName null while fileID is not AK_INVALID_FILE_ID, or vice versa) AkFileID fileID; ///< File ID. Only one of pszFileName or fileID should be valid (pszFileName null while fileID is not AK_INVALID_FILE_ID, or vice versa) AkFileSystemFlags* pFlags; ///< Flags for opening, null when unused AkOpenMode eOpenMode; ///< Open mode. }; #pragma pack(pop) //@} namespace AK { /// \name Profiling interfaces. //@{ /// Profiling interface of streams. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning class IAkStreamProfile { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkStreamProfile(){} public: /// Returns the stream's record (once). /// \sa /// - \ref streamingdevicemanager virtual void GetStreamRecord( AkStreamRecord & out_streamRecord ///< Returned stream record interface ) = 0; /// Returns the stream's statistics (every profile frame). /// \sa /// - \ref streamingdevicemanager virtual void GetStreamData( AkStreamData & out_streamData ///< Returned periodic stream data interface ) = 0; /// Query the stream's "new" flag. /// \return True, until AK::IAkStreamProfile::ClearNew() is called. /// \sa /// - \ref streamingdevicemanager virtual bool IsNew() = 0; /// Resets the stream's "new" flag. /// \sa /// - \ref streamingdevicemanager virtual void ClearNew() = 0; }; /// Profiling interface of high-level I/O devices. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning class IAkDeviceProfile { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkDeviceProfile(){} public: /// Notify device when monitor sampling starts. virtual void OnProfileStart() = 0; /// Notify device when monitor sampling ends. virtual void OnProfileEnd() = 0; /// Query the device's description (once). /// \sa /// - \ref streamingdevicemanager virtual void GetDesc( AkDeviceDesc & out_deviceDesc ///< Device descriptor. ) = 0; /// Query the device's statistics (at every profiling frame). /// \sa /// - \ref streamingdevicemanager virtual void GetData( AkDeviceData & out_deviceData ///< Device data. ) = 0; /// Query the device's "new" flag. /// \return True, until ClearNew() is called. /// \sa /// - \ref streamingdevicemanager virtual bool IsNew() = 0; /// Resets the device's "new" flag. /// \sa /// - \ref streamingdevicemanager virtual void ClearNew() = 0; /// Get the number of streams currently associated with that device. /// \return The number of streams /// \sa /// - \ref streamingdevicemanager virtual AkUInt32 GetNumStreams() = 0; /// Get a stream profile, for a specified stream index. /// \remarks GetStreamProfile() refers to streams by index, which must honor the call to AK::IAkDeviceProfile::GetNumStreams(). /// \sa /// - \ref streamingdevicemanager virtual IAkStreamProfile * GetStreamProfile( AkUInt32 in_uStreamIndex ///< Stream index: [0,numStreams[ ) = 0; }; /// Profiling interface of the Stream Manager. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning class IAkStreamMgrProfile { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkStreamMgrProfile(){} public: /// Start profile monitoring. /// \return AK_Success if successful, AK_Fail otherwise. /// \sa /// - \ref streamingdevicemanager virtual AKRESULT StartMonitoring() = 0; /// Stop profile monitoring. /// \sa /// - \ref streamingdevicemanager virtual void StopMonitoring() = 0; /// Device enumeration. /// \return The number of devices. /// \sa /// - \ref streamingdevicemanager virtual AkUInt32 GetNumDevices() = 0; /// Get a device profile for a specified device index. /// \remarks GetDeviceProfile() refers to devices by index, which must honor the call to AK::IAkStreamMgrProfile::GetNumDevices(). /// \remarks The device index is not the same as the device ID (AkDeviceID). /// \sa /// - \ref streamingdevicemanager virtual IAkDeviceProfile * GetDeviceProfile( AkUInt32 in_uDeviceIndex ///< Device index: [0,numDevices[ ) = 0; }; //@} /// \name High-level streams API. //@{ /// Interface of standard streams. Used as a handle to a standard stream. Has methods for /// stream control. Obtained through the Stream Manager's AK::IAkStreamMgr::CreateStd() method. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning class IAkStdStream { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkStdStream(){} public: /// \name Stream management and settings. //@{ /// Close the stream. The object is destroyed and the interface becomes invalid. /// \sa /// - \ref streamingdevicemanager virtual void Destroy() = 0; /// Get information about a stream. /// \sa /// - \ref streamingdevicemanager virtual void GetInfo( AkStreamInfo & out_info ///< Returned stream info ) = 0; /// Returns a unique cookie for a given stream. /// The default implementation of the Stream Manager returns its file descriptor (see AkStreamMgrModule.h). virtual void * GetFileDescriptor() = 0; /// Give the stream a name (appears in the Wwise Profiler). /// \sa /// - \ref streamingdevicemanager virtual AKRESULT SetStreamName( const AkOSChar * in_pszStreamName ///< Stream name ) = 0; /// Get the I/O block size. /// \remark Queries the low-level I/O, by calling AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize() with the /// stream's file descriptor. /// \return The block size, in bytes. /// \sa /// - \ref streamingdevicemanager virtual AkUInt32 GetBlockSize() = 0; //@} /// \name I/O operations. //@{ /// Schedule a read request. /// \warning Use only with a multiple of the block size, queried via AK::IAkStdStream::GetBlockSize(). /// \remarks If the call is asynchronous (in_bWait = false), wait until AK::IAkStdStream::GetStatus() stops returning AK_StmStatusPending. /// \return AK_Success if the operation was successfully scheduled (but not necessarily completed) /// \sa /// - \ref streamingdevicemanager virtual AKRESULT Read( void * in_pBuffer, ///< User buffer address AkUInt32 in_uReqSize, ///< Requested read size bool in_bWait, ///< Block until the operation is complete AkPriority in_priority, ///< Heuristic: operation priority AkReal32 in_fDeadline, ///< Heuristic: operation deadline (ms) AkUInt32 & out_uSize ///< The size that was actually read ) = 0; /// Schedule a write request. /// \warning Use only with a multiple of the block size, queried via AK::IAkStdStream::GetBlockSize(). /// \remarks If the call is asynchronous (in_bWait = false), wait until GetStatus() stops returning AK_StmStatusPending. /// \return AK_Success if the operation was successfully scheduled /// \sa /// - \ref streamingdevicemanager virtual AKRESULT Write( void * in_pBuffer, ///< User buffer address AkUInt32 in_uReqSize, ///< Requested write size bool in_bWait, ///< Block until the operation is complete AkPriority in_priority, ///< Heuristic: operation priority AkReal32 in_fDeadline, ///< Heuristic: operation deadline (ms) AkUInt32 & out_uSize ///< The size that was actually written ) = 0; /// Get the current stream position. /// \remarks If an operation is pending, there is no guarantee that the position was queried before (or after) the operation was completed. /// \return The current stream position /// \sa /// - \ref streamingdevicemanager virtual AkUInt64 GetPosition( bool * out_pbEndOfStream ///< Returned end-of-stream flag, only for streams opened with AK_OpenModeRead (can pass NULL) ) = 0; /// Set the stream position. Modifies the position for the next read/write operation. /// \warning No operation should be pending. /// \remarks The new position will snap to the lowest block boundary. /// \return AK_Success if the stream position was changed /// \sa /// - \ref streamingdevicemanager virtual AKRESULT SetPosition( AkInt64 in_iMoveOffset, ///< Seek offset AkMoveMethod in_eMoveMethod ///< Seek method, from the beginning, end, or current file position ) = 0; /// Cancel the current operation. /// \remarks When it returns, the caller is guaranteed that no operation is pending. /// \remarks This method can block the caller for the whole duration of the I/O operation, if the request was already posted. /// \sa /// - \ref streamingdevicemanager virtual void Cancel() = 0; //@} /// \name Access to data and status. //@{ /// Get user data (and accessed size). /// \return The address of data provided by user /// \sa /// - \ref streamingdevicemanager virtual void* GetData( AkUInt32& out_uSize ///< Size actually read or written ) = 0; /// Get the stream's status. /// \return The stream status. /// \sa /// - \ref streamingdevicemanager virtual AkStmStatus GetStatus() = 0; /// Block and wait for a pending read to finish, and return the current status of the stream. /// This will return immediately if the status is not pending. /// \return The stream status. /// \sa /// - \ref streamingdevicemanager virtual AkStmStatus WaitForPendingOperation() = 0; //@} }; /// Interface of automatic streams. It is used as a handle to a stream, /// I/O operations are triggered from here. /// Obtained through the Stream Manager's AK::IAkStreamMgr::CreateAuto() method. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning /// \sa /// - \ref streamingdevicemanager class IAkAutoStream { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkAutoStream(){} public: /// \name Stream management, settings access, and run-time change. //@{ /// Close the stream. The object is destroyed and the interface becomes invalid. /// \sa /// - \ref streamingdevicemanager virtual void Destroy() = 0; /// Get information about the stream. /// \sa /// - \ref streamingdevicemanager virtual void GetInfo( AkStreamInfo & out_info ///< Returned stream info ) = 0; /// Returns a unique cookie for a given stream. /// The default implementation of the Stream Manager returns its file descriptor (see AkStreamMgrModule.h). virtual void * GetFileDescriptor() = 0; /// Get the stream's heuristics. /// \sa /// - \ref streamingdevicemanager virtual void GetHeuristics( AkAutoStmHeuristics & out_heuristics///< Returned stream heuristics ) = 0; /// Run-time change of the stream's heuristics. /// \sa /// - \ref streamingdevicemanager virtual AKRESULT SetHeuristics( const AkAutoStmHeuristics & in_heuristics ///< New stream heuristics ) = 0; /// Run-time change of the stream's minimum buffer size that can be handed out to client /// in GetBuffer() (except the last buffer at the end of file). /// Corresponds to the uMinBufferSize field of the AkAutoStmBufSettings passed to CreateAuto(). /// \sa /// - AkAutoStmBufSettings /// - \ref streamingdevicemanager virtual AKRESULT SetMinimalBufferSize( AkUInt32 in_uMinBufferSize ///< Minimum buffer size that can be handed out to client. ) = 0; /// Give the stream a name (appears in the Wwise profiler). /// \sa /// - \ref streamingdevicemanager virtual AKRESULT SetStreamName( const AkOSChar * in_pszStreamName ///< Stream name ) = 0; /// Get the I/O block size. /// \remark Queries the actual low-level I/O device, by calling AK::StreamMgr::IAkLowLevelIOHook::GetBlockSize() with the /// stream's file descriptor. /// \return The block size (in bytes) /// \sa /// - \ref streamingdevicemanager virtual AkUInt32 GetBlockSize() = 0; /// Get the amount of buffering that the stream has. /// The buffering is defined as the number of bytes that the stream has buffered, excluding the number /// of bytes that is currently granted to the user (with GetBuffer()). /// \remark The returned value corresponds to the buffering status at that moment, and does not even /// guarantee that it will not shrink. /// \return /// - AK_DataReady: Some data has been buffered (out_uNumBytesAvailable is greater than 0). /// - AK_NoDataReady: No data is available, and the end of file has not been reached. /// - AK_NoMoreData: Some or no data is available, but the end of file has been reached. The stream will not buffer any more data. /// - AK_Fail: The stream is invalid due to an I/O error. virtual AKRESULT QueryBufferingStatus( AkUInt32 & out_uNumBytesAvailable ///< Number of bytes available in the stream's buffer(s). ) = 0; /// Returns the target buffering size based on the throughput heuristic. /// \return /// Target buffering length expressed in bytes. virtual AkUInt32 GetNominalBuffering() = 0; //@} /// \name Stream operations. //@{ /// Start the automatic scheduling. /// \return AK_Success if the automatic scheduling was started successfully /// \sa /// - \ref streamingdevicemanager virtual AKRESULT Start() = 0; /// Stop the automatic scheduling. /// \return AK_Success if the automatic scheduling was stopped successfully. /// \sa /// - \ref streamingdevicemanager virtual AKRESULT Stop() = 0; /// Get the stream's position. /// \remarks The stream position is the position seen by the user, not the position of the file /// already streamed into the Stream Manager's memory. The stream position is updated when buffers /// are released, using AK::IAkAutoStream::ReleaseBuffer(). /// \return The file position in bytes of the beginning of the first buffer owned by the user. /// If the user does not own a buffer, it returns the position of the beginning of the buffer that /// would be returned from a call to AK::IAkAutoStream::GetBuffer(). /// \sa /// - \ref streamingdevicemanager virtual AkUInt64 GetPosition( bool * out_pbEndOfStream ///< Returned end-of-stream flag (can pass NULL) ) = 0; /// Set the stream's position. /// The next call to AK::IAkAutoStream::GetBuffer() will grant data that corresponds to the position specified here. /// \remarks Data already streamed into the Stream Manager's memory might be flushed. /// \remarks The new position will round down to the low-level I/O block size. /// \return AK_Success if the resulting position is valid /// \sa /// - \ref streamingdevicemanager virtual AKRESULT SetPosition( AkInt64 in_iMoveOffset, ///< Seek offset AkMoveMethod in_eMoveMethod ///< Seek method, from the beginning, end or current file position| ) = 0; //@} /// \name Data/status access. //@{ /// Get data from the Stream Manager buffers. /// \remarks Grants a buffer if data is available. Each successful call to this method returns a new /// buffer of data, at the current stream position. /// Buffers should be released as soon as they are not needed, using AK::IAkAutoStream::ReleaseBuffer(). /// \aknote AK::IAkAutoStream::ReleaseBuffer() does not take any argument, because it releases buffers in order. \endaknote /// \return /// - AK_DataReady : the buffer was granted /// - AK_NoDataReady : the buffer is not granted yet (never happens when called with in_bWait flag) /// - AK_NoMoreData : the buffer was granted but reached end of file (next call will return with size 0) /// - AK_Fail : there was an I/O error /// \sa /// - \ref streamingdevicemanager virtual AKRESULT GetBuffer( void *& out_pBuffer, ///< Returned address of granted data space AkUInt32 & out_uSize, ///< Returned size of granted data space bool in_bWait ///< Block until data is ready ) = 0; /// Release buffer granted through GetBuffer(). Buffers are released in order. /// \return AK_Success if a valid buffer was released, AK_Fail if the user did not own any buffer. /// \note To implementers: Clients like the sound engine may release buffers until this function returns AK_Fail. /// Failing to release a buffer should not be considered as a fatal error. /// \sa /// - \ref streamingdevicemanager virtual AKRESULT ReleaseBuffer() = 0; //@} }; //@} /// Interface of the Stream Manager. /// \akwarning /// The functions in this interface are not thread-safe, unless stated otherwise. /// \endakwarning class IAkStreamMgr { protected: /// Virtual destructor on interface to avoid warnings. virtual ~IAkStreamMgr(){} public: /// Global access to singleton. /// \return The interface of the global Stream Manager /// \sa /// - \ref streamingdevicemanager inline static IAkStreamMgr * Get() { return m_pStreamMgr; } /// Destroy the Stream Manager. /// \sa /// - \ref streamingdevicemanager virtual void Destroy() = 0; /// \name Profiling. //@{ /// Get the profiling interface. /// \return The interface of the Stream Manager profiler virtual IAkStreamMgrProfile * GetStreamMgrProfile() = 0; //@} /// \name Stream creation interface. //@{ // Standard stream creation methods. /// Create a standard stream (string overload). /// \return AK_Success if the stream was created successfully /// \remarks The string overload of AK::StreamMgr::IAkFileLocationResolver::Open() will be called. /// \sa /// - \ref streamingdevicemanager virtual AKRESULT CreateStd( const AkFileOpenData& in_FileOpen, ///< File name or file ID (only one should be valid), open flags, open mode IAkStdStream *& out_pStream, ///< Returned interface to a standard stream. If the function does not return AK_Success, this pointer is left untouched. bool in_bSyncOpen ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion. ) = 0; // Automatic stream create methods. /// Create an automatic stream. /// \return AK_Success if the stream was created successfully /// \remarks Automatic streams can only be in Read mode. /// \remarks The stream needs to be started explicitly with AK::IAkAutoStream::Start(). /// \remarks This call will eventually delegate the operation to AK::StreamMgr::IAkFileLocationResolver::Open(). /// \sa /// - \ref streamingdevicemanager virtual AKRESULT CreateAuto( const AkFileOpenData& in_FileOpen, ///< File name or file ID (only one should be valid), open flags, open mode const AkAutoStmHeuristics & in_heuristics, ///< Streaming heuristics AkAutoStmBufSettings * in_pBufferSettings, ///< Stream buffer settings (it is recommended to pass NULL in order to use the default settings) IAkAutoStream *& out_pStream, ///< Returned interface to an automatic stream. If the function does not return AK_Success, this pointer is left untouched. bool in_bSyncOpen, ///< If true, force the Stream Manager to open file synchronously. Otherwise, it is left to its discretion. bool in_bCaching = false ///< Does this stream stay in cache ) = 0; /// Create an automatic stream (in-memory buffer overload). /// /// This overload differs largely from CreateAuto() implementations, which are file based. /// This version is provided with a memory space and the resulting automatic stream will simply /// return the memory space in a similar fashion, but without the need to perform any actual file operations. /// /// If you are in the process of implementing your own IAkStreamMgr object, /// consider using the initial implementation from `\\SDK\\source\\StreamManager\\Common\\AkStreamMgr.cpp`. /// /// \return AK_Success if the stream was created successfully /// \remarks The stream needs to be started explicitly with IAkAutoStream::Start(). /// \sa /// - \ref streamingdevicemanager virtual AKRESULT CreateAuto( void * in_pBuffer, ///< Pointer to the memory area containing stream data AkUInt64 in_uSize, ///< Size of the memory area containing stream data const AkAutoStmHeuristics & in_heuristics, ///< Streaming heuristics IAkAutoStream *& out_pStream ///< Returned interface to an automatic stream. If the function does not return AK_Success, this pointer is left untouched. ) = 0; /// Start streaming the first "in_pFSFlags->uNumBytesPrefetch" bytes of the file with id "in_fileID" into cache. The stream will be scheduled only after /// all regular streams (not file caching streams) are serviced. The file will stay cached until either the UnpinFileInCache is called, /// or the limit as set by uMaxCachePinnedBytes is reached and another higher priority file (in_uPriority) needs the space. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API. /// Using PinFileInCache() directly does not allow users to take advantage of sound bank data. The file and the number of bytes they wish to cache must be explicitly specified. /// /// \sa /// - \ref streamingdevicemanager /// - AK::SoundEngine::PinEventInStreamCache /// - AK::SoundEngine::UnpinEventInStreamCache /// - AkFileSystemFlags virtual AKRESULT PinFileInCache( AkFileID in_fileID, ///< Application-defined ID AkFileSystemFlags * in_pFSFlags, ///< Special file system flags (can NOT pass NULL) AkPriority in_uPriority ///< Stream caching priority. Note: Caching requests only get serviced after all regular streaming requests. ) = 0; /// Un-pin a file that has been previouly pinned into cache. This function must be called once for every call to PinFileInCache() with the same file id. /// The file may still remain in stream cache after this is called, until the memory is reused by the streaming memory manager in accordance with to its /// cache management algorithm. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API. /// Using UnpinFileInCache() directly does not allow users to take advantage of sound bank data. The file must be explicitly specified. /// \sa /// - \ref streamingdevicemanager /// - AK::SoundEngine::PinEventInStreamCache /// - AK::SoundEngine::UnpinEventInStreamCache virtual AKRESULT UnpinFileInCache( AkFileID in_fileID, ///< Application-defined ID AkPriority in_uPriority ///< Priority of stream that you are unpinning ) = 0; /// Update the priority of the caching stream. Higher priority streams will be serviced before lower priority caching streams, and will be more likely to stay in /// memory if the cache pin limit as set by "uMaxCachePinnedBytes" is reached. /// \remarks PinFileInCache()/UnpinFileInCache()/UpdateCachingPriority() are typically not used directly, but instead used via the AK::SoundEngine::PinEventInStreamCache() API. /// Using UpdateCachingPriority() directly does not allow users to take advantage of sound bank data. The file must be explicitly specified. /// \sa /// - \ref streamingdevicemanager /// - AK::SoundEngine::PinEventInStreamCache /// - AK::SoundEngine::UnpinEventInStreamCache virtual AKRESULT UpdateCachingPriority( AkFileID in_fileID, ///< Application-defined ID AkPriority in_uPriority, ///< Priority AkPriority in_uOldPriority ///< Old priority ) = 0; /// Return information about a file that has been pinned into cache. /// Retrieves the percentage of the requested buffer size that has been streamed in and stored into stream cache, and whether /// the cache pinned memory limit is preventing this buffer from filling. virtual AKRESULT GetBufferStatusForPinnedFile( AkFileID in_fileID, ///< Application-defined ID AkReal32& out_fPercentBuffered, ///< Percentage of buffer full (out of 100) bool& out_bCacheFull ///< Set to true if the rest of the buffer can not fit into the cache-pinned memory limit. ) = 0; /// Make a memory stream point to a new area in memory, otherwise keeping the exact same state. virtual AKRESULT RelocateMemoryStream( IAkAutoStream * in_pStream, ///< The stream to relocate. Must be a stream created with the memory overload of CreateAutoStm. AkUInt8 * in_pNewStart ///< The new area in memory to point to ) = 0; //@} protected: /// Definition of the global pointer to the interface of the Stream Manager singleton. /// \sa /// - \ref streamingdevicemanager static AKSOUNDENGINE_API IAkStreamMgr * m_pStreamMgr; }; } #endif //_IAK_STREAM_MGR_H_