Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
16 KiB

  1. /*-========================================================================-_
  2. | - XAPO - |
  3. | Copyright (c) Microsoft Corporation. All rights reserved. |
  4. |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  5. |PROJECT: XAPO MODEL: Unmanaged User-mode |
  6. |VERSION: 1.0 EXCEPT: No Exceptions |
  7. |CLASS: N / A MINREQ: WinXP, Xbox360 |
  8. |BASE: N / A DIALECT: MSC++ 14.00 |
  9. |>------------------------------------------------------------------------<|
  10. | DUTY: XAPO base classes |
  11. ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  12. NOTES:
  13. 1. See XAPO.h for the rules governing XAPO interface behaviour. */
  14. #pragma once
  15. //--------------<D-E-F-I-N-I-T-I-O-N-S>-------------------------------------//
  16. #include "XAPO.h"
  17. // default audio format ranges supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat
  18. #define XAPOBASE_DEFAULT_FORMAT_TAG WAVE_FORMAT_IEEE_FLOAT // 32-bit float only, applies to WAVEFORMATEX.wFormatTag or WAVEFORMATEXTENSIBLE.SubFormat when used
  19. #define XAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS XAPO_MIN_CHANNELS // minimum channel count, applies to WAVEFORMATEX.nChannels
  20. #define XAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS XAPO_MAX_CHANNELS // maximum channel count, applies to WAVEFORMATEX.nChannels
  21. #define XAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE XAPO_MIN_FRAMERATE // minimum framerate, applies to WAVEFORMATEX.nSamplesPerSec
  22. #define XAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE XAPO_MAX_FRAMERATE // maximum framerate, applies to WAVEFORMATEX.nSamplesPerSec
  23. #define XAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE 32 // 32-bit float only, applies to WAVEFORMATEX.wBitsPerSample and WAVEFORMATEXTENSIBLE.wValidBitsPerSample when used
  24. // default XAPO property flags supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
  25. #define XAPOBASE_DEFAULT_FLAG (XAPO_FLAG_CHANNELS_MUST_MATCH | XAPO_FLAG_FRAMERATE_MUST_MATCH | XAPO_FLAG_BITSPERSAMPLE_MUST_MATCH | XAPO_FLAG_BUFFERCOUNT_MUST_MATCH | XAPO_FLAG_INPLACE_SUPPORTED)
  26. // default number of input and output buffers supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
  27. #define XAPOBASE_DEFAULT_BUFFER_COUNT 1
  28. //--------------<D-A-T-A---T-Y-P-E-S>---------------------------------------//
  29. #pragma pack(push, 8) // set packing alignment to ensure consistency across arbitrary build environments
  30. // primitive types
  31. typedef float FLOAT32; // 32-bit IEEE float
  32. ////
  33. // DESCRIPTION:
  34. // Default implementation of the IXAPO and IUnknown interfaces.
  35. // Provides overridable implementations for all methods save IXAPO::Process.
  36. ////
  37. class __declspec(novtable) CXAPOBase: public IXAPO {
  38. private:
  39. const XAPO_REGISTRATION_PROPERTIES* m_pRegistrationProperties; // pointer to registration properties of the XAPO, set via constructor
  40. void* m_pfnMatrixMixFunction; // optimal matrix function pointer, used for thru processing
  41. FLOAT32* m_pfl32MatrixCoefficients; // matrix coefficient table, used for thru processing
  42. UINT32 m_nSrcFormatType; // input format type, used for thru processing
  43. BOOL m_fIsScalarMatrix; // TRUE if m_pfl32MatrixCoefficients is diagonal matrix with all main diagonal entries equal, i.e. m_pfnMatrixMixFunction only used for type conversion (no channel conversion), used for thru processing
  44. BOOL m_fIsLocked; // TRUE if XAPO locked via CXAPOBase.LockForProcess
  45. protected:
  46. LONG m_lReferenceCount; // COM reference count, must be aligned for atomic operations
  47. ////
  48. // DESCRIPTION:
  49. // Verifies an audio format falls within the default ranges supported.
  50. //
  51. // REMARKS:
  52. // If pFormat is unsupported, and fOverwrite is TRUE,
  53. // pFormat is overwritten with the nearest format supported.
  54. // Nearest meaning closest bit depth, framerate, and channel count,
  55. // in that order of importance.
  56. //
  57. // PARAMETERS:
  58. // pFormat - [in/out] audio format to examine
  59. // fOverwrite - [in] TRUE to overwrite pFormat if audio format unsupported
  60. //
  61. // RETURN VALUE:
  62. // COM error code, including:
  63. // S_OK - audio format supported, pFormat left untouched
  64. // XAPO_E_FORMAT_UNSUPPORTED - audio format unsupported, pFormat overwritten with nearest audio format supported if fOverwrite TRUE
  65. // E_INVALIDARG - audio format invalid, pFormat left untouched
  66. ////
  67. virtual HRESULT ValidateFormatDefault (__inout WAVEFORMATEX* pFormat, BOOL fOverwrite);
  68. ////
  69. // DESCRIPTION:
  70. // Verifies that an input/output format pair configuration is supported
  71. // with respect to the XAPO property flags.
  72. //
  73. // REMARKS:
  74. // If pRequestedFormat is unsupported, and fOverwrite is TRUE,
  75. // pRequestedFormat is overwritten with the nearest format supported.
  76. // Nearest meaning closest bit depth, framerate, and channel count,
  77. // in that order of importance.
  78. //
  79. // PARAMETERS:
  80. // pSupportedFormat - [in] audio format known to be supported
  81. // pRequestedFormat - [in/out] audio format to examine, must be WAVEFORMATEXTENSIBLE if fOverwrite TRUE
  82. // fOverwrite - [in] TRUE to overwrite pRequestedFormat if input/output configuration unsupported
  83. //
  84. // RETURN VALUE:
  85. // COM error code, including:
  86. // S_OK - input/output configuration supported, pRequestedFormat left untouched
  87. // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, pRequestedFormat overwritten with nearest audio format supported if fOverwrite TRUE
  88. // E_INVALIDARG - either audio format invalid, pRequestedFormat left untouched
  89. ////
  90. HRESULT ValidateFormatPair (const WAVEFORMATEX* pSupportedFormat, __inout WAVEFORMATEX* pRequestedFormat, BOOL fOverwrite);
  91. ////
  92. // DESCRIPTION:
  93. // This method may be called by an IXAPO::Process implementation
  94. // for thru processing. It copies/mixes data from source to
  95. // destination, making as few changes as possible to the audio data.
  96. //
  97. // REMARKS:
  98. // However, this method is capable of channel upmix/downmix and uses
  99. // the same matrix coefficient table used by windows Vista to do so.
  100. //
  101. // For in-place processing (input buffer == output buffer)
  102. // this method does nothing.
  103. //
  104. // This method should be called only if the XAPO is locked and
  105. // XAPO_FLAG_FRAMERATE_MUST_MATCH is used.
  106. //
  107. // PARAMETERS:
  108. // pInputBuffer - [in] input buffer, format may be INT8, INT16, INT20 (contained in 24 or 32 bits), INT24 (contained in 24 or 32 bits), INT32, or FLOAT32
  109. // pOutputBuffer - [out] output buffer, format must be FLOAT32
  110. // FrameCount - [in] number of frames to process
  111. // InputChannelCount - [in] number of input channels
  112. // OutputChannelCount - [in] number of output channels
  113. // MixWithOutput - [in] TRUE to mix with output, FALSE to overwrite output
  114. //
  115. // RETURN VALUE:
  116. // void
  117. ////
  118. void ProcessThru (__in void* pInputBuffer, __inout FLOAT32* pOutputBuffer, UINT32 FrameCount, WORD InputChannelCount, WORD OutputChannelCount, BOOL MixWithOutput);
  119. // accessors
  120. const XAPO_REGISTRATION_PROPERTIES* GetRegistrationPropertiesInternal () { return m_pRegistrationProperties; }
  121. BOOL IsLocked () { return m_fIsLocked; }
  122. public:
  123. CXAPOBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties);
  124. virtual ~CXAPOBase ();
  125. // IUnknown methods:
  126. // retrieves the requested interface pointer if supported
  127. STDMETHOD(QueryInterface) (REFIID riid, __deref_out void** ppInterface)
  128. {
  129. HRESULT hr = S_OK;
  130. if (riid == __uuidof(IXAPO)) {
  131. *ppInterface = static_cast<IXAPO*>(this);
  132. AddRef();
  133. } else if (riid == __uuidof(IUnknown)) {
  134. *ppInterface = static_cast<IUnknown*>(this);
  135. AddRef();
  136. } else {
  137. *ppInterface = NULL;
  138. hr = E_NOINTERFACE;
  139. }
  140. return hr;
  141. }
  142. // increments reference count
  143. STDMETHOD_(ULONG, AddRef) ()
  144. {
  145. return (ULONG)InterlockedIncrement(&m_lReferenceCount);
  146. }
  147. // decrements reference count and deletes the object if the reference count falls to zero
  148. STDMETHOD_(ULONG, Release) ()
  149. {
  150. ULONG uTmpReferenceCount = (ULONG)InterlockedDecrement(&m_lReferenceCount);
  151. if (uTmpReferenceCount == 0) {
  152. delete this;
  153. }
  154. return uTmpReferenceCount;
  155. }
  156. // IXAPO methods:
  157. // Allocates a copy of the registration properties of the XAPO.
  158. // This default implementation returns a copy of the registration
  159. // properties given to the constructor, allocated via XAPOAlloc.
  160. STDMETHOD(GetRegistrationProperties) (__deref_out XAPO_REGISTRATION_PROPERTIES** ppRegistrationProperties);
  161. // Queries if a specific input format is supported for a given output format.
  162. // This default implementation assumes only the format described by the
  163. // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
  164. STDMETHOD(IsInputFormatSupported) (const WAVEFORMATEX* pOutputFormat, const WAVEFORMATEX* pRequestedInputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedInputFormat);
  165. // Queries if a specific output format is supported for a given input format.
  166. // This default implementation assumes only the format described by the
  167. // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
  168. STDMETHOD(IsOutputFormatSupported) (const WAVEFORMATEX* pInputFormat, const WAVEFORMATEX* pRequestedOutputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedOutputFormat);
  169. // Performs any effect-specific initialization.
  170. // This default implementation is a no-op and only returns S_OK.
  171. STDMETHOD(Initialize) (__in_bcount_opt(DataByteSize) const void*, UINT32 DataByteSize)
  172. {
  173. UNREFERENCED_PARAMETER(DataByteSize);
  174. return S_OK;
  175. }
  176. // Resets variables dependent on frame history.
  177. // This default implementation is a no-op: this base class contains no
  178. // relevant state to reset.
  179. STDMETHOD_(void, Reset) () { return; }
  180. // Notifies XAPO of buffer formats Process() will be given.
  181. // This default implementation performs basic input/output format
  182. // validation against the XAPO's registration properties.
  183. // Derived XAPOs should call the base implementation first.
  184. STDMETHOD(LockForProcess) (UINT32 InputLockedParameterCount, __in_ecount_opt(InputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters, UINT32 OutputLockedParameterCount, __in_ecount_opt(OutputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters);
  185. // Opposite of LockForProcess.
  186. // Derived XAPOs should call the base implementation first.
  187. STDMETHOD_(void, UnlockForProcess) ();
  188. // Returns the number of input frames required to generate the requested number of output frames.
  189. // By default, this method returns the same number of frames it was passed.
  190. STDMETHOD_(UINT32, CalcInputFrames) (UINT32 OutputFrameCount) { return OutputFrameCount; }
  191. // Returns the number of output frames generated for the requested number of input frames.
  192. // By default, this method returns the same number of frames it was passed.
  193. STDMETHOD_(UINT32, CalcOutputFrames) (UINT32 InputFrameCount) { return InputFrameCount; }
  194. };
  195. //--------------------------------------------------------------------------//
  196. ////
  197. // DESCRIPTION:
  198. // Extends CXAPOBase, providing a default implementation of the
  199. // IXAPOParameters interface with appropriate synchronization to
  200. // protect variables shared between IXAPOParameters::GetParameters
  201. // and IXAPOParameters::SetParameters/IXAPO::Process.
  202. //
  203. // This class is for parameter blocks whose size is larger than 4 bytes.
  204. // For smaller parameter blocks, use atomic operations directly
  205. // on the parameters for synchronization.
  206. ////
  207. class __declspec(novtable) CXAPOParametersBase: public CXAPOBase, public IXAPOParameters {
  208. private:
  209. BYTE* m_pParameterBlocks; // three contiguous process parameter blocks used for synchronization, user responsible for initialization of parameter blocks before IXAPO::Process/SetParameters/GetParameters called
  210. BYTE* m_pCurrentParameters; // pointer to current process parameters, must be aligned for atomic operations
  211. BYTE* m_pCurrentParametersInternal; // pointer to current process parameters (temp pointer read by SetParameters/BeginProcess/EndProcess)
  212. UINT32 m_uCurrentParametersIndex; // index of current process parameters
  213. UINT32 m_uParameterBlockByteSize; // size of a single parameter block in bytes, must be > 0
  214. BOOL m_fNewerResultsReady; // TRUE if there exists new processing results not yet picked up by GetParameters(), must be aligned for atomic operations
  215. BOOL m_fProducer; // IXAPO::Process produces data to be returned by GetParameters(); SetParameters() disallowed
  216. public:
  217. ////
  218. // PARAMETERS:
  219. // pRegistrationProperties - [in] registration properties of the XAPO
  220. // pParameterBlocks - [in] three contiguous process parameter blocks used for synchronization
  221. // uParameterBlockByteSize - [in] size of one of the parameter blocks, must be > 0
  222. // fProducer - [in] TRUE if IXAPO::Process produces data to be returned by GetParameters() (SetParameters() and ParametersChanged() disallowed)
  223. ////
  224. CXAPOParametersBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties, BYTE* pParameterBlocks, UINT32 uParameterBlockByteSize, BOOL fProducer);
  225. virtual ~CXAPOParametersBase ();
  226. // IUnknown methods:
  227. // retrieves the requested interface pointer if supported
  228. STDMETHOD(QueryInterface) (REFIID riid, __deref_out void** ppInterface)
  229. {
  230. HRESULT hr = S_OK;
  231. if (riid == __uuidof(IXAPOParameters)) {
  232. *ppInterface = static_cast<IXAPOParameters*>(this);
  233. CXAPOBase::AddRef();
  234. } else {
  235. hr = CXAPOBase::QueryInterface(riid, ppInterface);
  236. }
  237. return hr;
  238. }
  239. // increments reference count
  240. STDMETHOD_(ULONG, AddRef)() { return CXAPOBase::AddRef(); }
  241. // decrements reference count and deletes the object if the reference count falls to zero
  242. STDMETHOD_(ULONG, Release)() { return CXAPOBase::Release(); }
  243. // IXAPOParameters methods:
  244. // Sets effect-specific parameters.
  245. // This method may only be called on the realtime audio processing thread.
  246. STDMETHOD_(void, SetParameters) (__in_bcount(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize);
  247. // Gets effect-specific parameters.
  248. // This method may block and should not be called from the realtime thread.
  249. // Get the current parameters via BeginProcess.
  250. STDMETHOD_(void, GetParameters) (__out_bcount(ParameterByteSize) void* pParameters, UINT32 ParameterByteSize);
  251. // Called by SetParameters() to allow for user-defined parameter validation.
  252. // SetParameters validates that ParameterByteSize == m_uParameterBlockByteSize
  253. // so the user may assume/assert ParameterByteSize == m_uParameterBlockByteSize.
  254. // This method should not block as it is called from the realtime thread.
  255. virtual void OnSetParameters (const void*, UINT32) { }
  256. // Returns TRUE if SetParameters() has been called since the last processing pass.
  257. // May only be used within the XAPO's IXAPO::Process implementation,
  258. // before BeginProcess is called.
  259. BOOL ParametersChanged ();
  260. // Returns latest process parameters.
  261. // XAPOs must call this method within their IXAPO::Process
  262. // implementation to access latest process parameters in threadsafe manner.
  263. BYTE* BeginProcess ();
  264. // Notifies CXAPOParametersBase that the XAPO has finished accessing
  265. // the latest process parameters.
  266. // XAPOs must call this method within their IXAPO::Process
  267. // implementation to access latest process parameters in threadsafe manner.
  268. void EndProcess ();
  269. };
  270. #pragma pack(pop) // revert packing alignment
  271. //---------------------------------<-EOF->----------------------------------//