RetroArch
xapobase.h
Go to the documentation of this file.
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 
15 #ifdef _MSC_VER
16 #pragma once
17 #endif
18 
19 //--------------<D-E-F-I-N-I-T-I-O-N-S>-------------------------------------//
20 #include "XAPO.h"
21 
22 // default audio format ranges supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat
23 #define XAPOBASE_DEFAULT_FORMAT_TAG WAVE_FORMAT_IEEE_FLOAT // 32-bit float only, applies to WAVEFORMATEX.wFormatTag or WAVEFORMATEXTENSIBLE.SubFormat when used
24 #define XAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS XAPO_MIN_CHANNELS // minimum channel count, applies to WAVEFORMATEX.nChannels
25 #define XAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS XAPO_MAX_CHANNELS // maximum channel count, applies to WAVEFORMATEX.nChannels
26 #define XAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE XAPO_MIN_FRAMERATE // minimum framerate, applies to WAVEFORMATEX.nSamplesPerSec
27 #define XAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE XAPO_MAX_FRAMERATE // maximum framerate, applies to WAVEFORMATEX.nSamplesPerSec
28 #define XAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE 32 // 32-bit float only, applies to WAVEFORMATEX.wBitsPerSample and WAVEFORMATEXTENSIBLE.wValidBitsPerSample when used
29 
30 // default XAPO property flags supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
31 #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)
32 
33 // default number of input and output buffers supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
34 #define XAPOBASE_DEFAULT_BUFFER_COUNT 1
35 
36 
37 //--------------<M-A-C-R-O-S>-----------------------------------------------//
38 // assertion
39 #if !defined(XAPOASSERT)
40  #if XAPODEBUG
41  #define XAPOASSERT(exp) if (!(exp)) { OutputDebugStringA("XAPO ASSERT: " #exp ", {" __FUNCTION__ "}\n"); __debugbreak(); }
42  #else
43  #define XAPOASSERT(exp) __assume(exp)
44  #endif
45 #endif
46 #if !defined(XAPOASSERT_NO_OUTPUT)
47  #if XAPODEBUG
48  #define XAPOASSERT_NO_OUTPUT(exp) if (!(exp)) { __debugbreak(); }
49  #else
50  #define XAPOASSERT_NO_OUTPUT(exp) __assume(exp)
51  #endif
52 #endif
53 
54 
55 //--------------<D-A-T-A---T-Y-P-E-S>---------------------------------------//
56 #pragma pack(push, 8) // set packing alignment to ensure consistency across arbitrary build environments, and ensure synchronization variables used by Interlocked functionality are correctly aligned
57 
58 
59 // primitive types
60 typedef float FLOAT32; // 32-bit IEEE float
61 
62 
64  // DESCRIPTION:
65  // Default implementation of the IXAPO and IUnknown interfaces.
66  // Provides overridable implementations for all methods save IXAPO::Process.
68 class __declspec(novtable) CXAPOBase: public IXAPO {
69 private:
70  const XAPO_REGISTRATION_PROPERTIES* m_pRegistrationProperties; // pointer to registration properties of the XAPO, set via constructor
71 
72  void* m_pfnMatrixMixFunction; // optimal matrix function pointer, used for thru processing
73  FLOAT32* m_pfl32MatrixCoefficients; // matrix coefficient table, used for thru processing
74  UINT32 m_nSrcFormatType; // input format type, used for thru processing
75  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
76  BOOL m_fIsLocked; // TRUE if XAPO locked via CXAPOBase.LockForProcess
77 
78 
79 protected:
80  LONG m_lReferenceCount; // COM reference count, must be aligned for atomic operations
81 
83  // DESCRIPTION:
84  // Verifies an audio format falls within the default ranges supported.
85  //
86  // REMARKS:
87  // If pFormat is unsupported, and fOverwrite is TRUE,
88  // pFormat is overwritten with the nearest format supported.
89  // Nearest meaning closest bit depth, framerate, and channel count,
90  // in that order of importance.
91  //
92  // PARAMETERS:
93  // pFormat - [in/out] audio format to examine
94  // fOverwrite - [in] TRUE to overwrite pFormat if audio format unsupported
95  //
96  // RETURN VALUE:
97  // COM error code, including:
98  // S_OK - audio format supported, pFormat left untouched
99  // XAPO_E_FORMAT_UNSUPPORTED - audio format unsupported, pFormat overwritten with nearest audio format supported if fOverwrite TRUE
100  // E_INVALIDARG - audio format invalid, pFormat left untouched
102  virtual HRESULT ValidateFormatDefault (_Inout_ WAVEFORMATEX* pFormat, BOOL fOverwrite);
103 
105  // DESCRIPTION:
106  // Verifies that an input/output format pair configuration is supported
107  // with respect to the XAPO property flags.
108  //
109  // REMARKS:
110  // If pRequestedFormat is unsupported, and fOverwrite is TRUE,
111  // pRequestedFormat is overwritten with the nearest format supported.
112  // Nearest meaning closest bit depth, framerate, and channel count,
113  // in that order of importance.
114  //
115  // PARAMETERS:
116  // pSupportedFormat - [in] audio format known to be supported
117  // pRequestedFormat - [in/out] audio format to examine, must be WAVEFORMATEXTENSIBLE if fOverwrite TRUE
118  // fOverwrite - [in] TRUE to overwrite pRequestedFormat if input/output configuration unsupported
119  //
120  // RETURN VALUE:
121  // COM error code, including:
122  // S_OK - input/output configuration supported, pRequestedFormat left untouched
123  // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, pRequestedFormat overwritten with nearest audio format supported if fOverwrite TRUE
124  // E_INVALIDARG - either audio format invalid, pRequestedFormat left untouched
126  HRESULT ValidateFormatPair (const WAVEFORMATEX* pSupportedFormat, _Inout_ WAVEFORMATEX* pRequestedFormat, BOOL fOverwrite);
127 
129  // DESCRIPTION:
130  // This method may be called by an IXAPO::Process implementation
131  // for thru processing. It copies/mixes data from source to
132  // destination, making as few changes as possible to the audio data.
133  //
134  // REMARKS:
135  // However, this method is capable of channel upmix/downmix and uses
136  // the same matrix coefficient table used by windows Vista to do so.
137  //
138  // For in-place processing (input buffer == output buffer)
139  // this method does nothing.
140  //
141  // This method should be called only if the XAPO is locked and
142  // XAPO_FLAG_FRAMERATE_MUST_MATCH is used.
143  //
144  // PARAMETERS:
145  // 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
146  // pOutputBuffer - [out] output buffer, format must be FLOAT32
147  // FrameCount - [in] number of frames to process
148  // InputChannelCount - [in] number of input channels
149  // OutputChannelCount - [in] number of output channels
150  // MixWithOutput - [in] TRUE to mix with output, FALSE to overwrite output
151  //
152  // RETURN VALUE:
153  // void
155  void ProcessThru (const void* pInputBuffer, _Inout_updates_(FrameCount*OutputChannelCount) FLOAT32* pOutputBuffer, UINT32 FrameCount, UINT32 InputChannelCount, UINT32 OutputChannelCount, BOOL MixWithOutput);
156 
157  // accessors
158  const XAPO_REGISTRATION_PROPERTIES* GetRegistrationPropertiesInternal () { return m_pRegistrationProperties; }
159  BOOL IsLocked () { return m_fIsLocked; }
160 
161 
162 public:
163  CXAPOBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties);
164  virtual ~CXAPOBase ();
165 
166  // IUnknown methods:
167  // retrieves the requested interface pointer if supported
168  STDMETHOD(QueryInterface) (REFIID riid, _Outptr_ void** ppInterface)
169  {
170  XAPOASSERT(ppInterface != NULL);
171  HRESULT hr = S_OK;
172 
173  if (riid == __uuidof(IXAPO)) {
174  *ppInterface = static_cast<IXAPO*>(this);
175  AddRef();
176  } else if (riid == __uuidof(IUnknown)) {
177  *ppInterface = static_cast<IUnknown*>(this);
178  AddRef();
179  } else {
180  *ppInterface = NULL;
181  hr = E_NOINTERFACE;
182  }
183 
184  return hr;
185  }
186 
187  // increments reference count
188  STDMETHOD_(ULONG, AddRef) ()
189  {
190  return (ULONG)InterlockedIncrement(&m_lReferenceCount);
191  }
192 
193  // decrements reference count and deletes the object if the reference count falls to zero
194  STDMETHOD_(ULONG, Release) ()
195  {
196  ULONG uTmpReferenceCount = (ULONG)InterlockedDecrement(&m_lReferenceCount);
197  if (uTmpReferenceCount == 0) {
198  delete this;
199  }
200  return uTmpReferenceCount;
201  }
202 
203  // IXAPO methods:
204  // Allocates a copy of the registration properties of the XAPO.
205  // This default implementation returns a copy of the registration
206  // properties given to the constructor, allocated via XAPOAlloc.
207  STDMETHOD(GetRegistrationProperties) (_Outptr_ XAPO_REGISTRATION_PROPERTIES** ppRegistrationProperties);
208 
209  // Queries if a specific input format is supported for a given output format.
210  // This default implementation assumes only the format described by the
211  // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
212  STDMETHOD(IsInputFormatSupported) (const WAVEFORMATEX* pOutputFormat, const WAVEFORMATEX* pRequestedInputFormat, _Outptr_opt_ WAVEFORMATEX** ppSupportedInputFormat);
213 
214  // Queries if a specific output format is supported for a given input format.
215  // This default implementation assumes only the format described by the
216  // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
217  STDMETHOD(IsOutputFormatSupported) (const WAVEFORMATEX* pInputFormat, const WAVEFORMATEX* pRequestedOutputFormat, _Outptr_opt_ WAVEFORMATEX** ppSupportedOutputFormat);
218 
219  // Performs any effect-specific initialization.
220  // This default implementation is a no-op and only returns S_OK.
221  STDMETHOD(Initialize) (_In_reads_bytes_opt_(DataByteSize) const void*, UINT32 DataByteSize)
222  {
223  UNREFERENCED_PARAMETER(DataByteSize);
224  return S_OK;
225  }
226 
227  // Resets variables dependent on frame history.
228  // This default implementation is a no-op: this base class contains no
229  // relevant state to reset.
230  STDMETHOD_(void, Reset) () { return; }
231 
232  // Notifies XAPO of buffer formats Process() will be given.
233  // This default implementation performs basic input/output format
234  // validation against the XAPO's registration properties.
235  // Derived XAPOs should call the base implementation first.
236  STDMETHOD(LockForProcess) (_Pre_equal_to_(OutputLockedParameterCount) UINT32 InputLockedParameterCount, _In_reads_opt_(InputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters, _Pre_equal_to_(InputLockedParameterCount) UINT32 OutputLockedParameterCount, _In_reads_opt_(OutputLockedParameterCount) const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters);
237 
238  // Opposite of LockForProcess.
239  // Derived XAPOs should call the base implementation first.
240  STDMETHOD_(void, UnlockForProcess) ();
241 
242  // Returns the number of input frames required to generate the requested number of output frames.
243  // By default, this method returns the same number of frames it was passed.
244  STDMETHOD_(UINT32, CalcInputFrames) (UINT32 OutputFrameCount) { return OutputFrameCount; }
245 
246  // Returns the number of output frames generated for the requested number of input frames.
247  // By default, this method returns the same number of frames it was passed.
248  STDMETHOD_(UINT32, CalcOutputFrames) (UINT32 InputFrameCount) { return InputFrameCount; }
249 };
250 
251 
252 
253 
254 
255 //--------------------------------------------------------------------------//
257  // DESCRIPTION:
258  // Extends CXAPOBase, providing a default implementation of the
259  // IXAPOParameters interface with appropriate synchronization to
260  // protect variables shared between IXAPOParameters::GetParameters
261  // and IXAPOParameters::SetParameters/IXAPO::Process.
262  //
263  // This class is for parameter blocks whose size is larger than 4 bytes.
264  // For smaller parameter blocks, use atomic operations directly
265  // on the parameters for synchronization.
267 class __declspec(novtable) CXAPOParametersBase: public CXAPOBase, public IXAPOParameters {
268 private:
269  BYTE* m_pParameterBlocks; // three contiguous process parameter blocks used for synchronization, user responsible for initialization of parameter blocks before IXAPO::Process/SetParameters/GetParameters called
270  BYTE* m_pCurrentParameters; // pointer to current process parameters, must be aligned for atomic operations
271  BYTE* m_pCurrentParametersInternal; // pointer to current process parameters (temp pointer read by SetParameters/BeginProcess/EndProcess)
272  UINT32 m_uCurrentParametersIndex; // index of current process parameters
273  UINT32 m_uParameterBlockByteSize; // size of a single parameter block in bytes, must be > 0
274  BOOL m_fNewerResultsReady; // TRUE if there exists new processing results not yet picked up by GetParameters(), must be aligned for atomic operations
275  BOOL m_fProducer; // TRUE if IXAPO::Process produces data to be returned by GetParameters(), SetParameters() and ParametersChanged() disallowed
276 
277 
278 public:
280  // PARAMETERS:
281  // pRegistrationProperties - [in] registration properties of the XAPO
282  // pParameterBlocks - [in] three contiguous process parameter blocks used for synchronization
283  // uParameterBlockByteSize - [in] size of one of the parameter blocks, must be > 0, should be > 4
284  // fProducer - [in] TRUE if IXAPO::Process produces data to be returned by GetParameters() (SetParameters() and ParametersChanged() disallowed)
286  CXAPOParametersBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties, _In_reads_bytes_opt_(3*uParameterBlockByteSize) BYTE* pParameterBlocks, UINT32 uParameterBlockByteSize, BOOL fProducer);
287  virtual ~CXAPOParametersBase ();
288 
289  // IUnknown methods:
290  // retrieves the requested interface pointer if supported
291  STDMETHOD(QueryInterface) (REFIID riid, _Outptr_result_maybenull_ void** ppInterface)
292  {
293  XAPOASSERT(ppInterface != NULL);
294  HRESULT hr = S_OK;
295 
296  if (riid == __uuidof(IXAPOParameters)) {
297  *ppInterface = static_cast<IXAPOParameters*>(this);
298  CXAPOBase::AddRef();
299  } else {
300  hr = CXAPOBase::QueryInterface(riid, ppInterface);
301  }
302 
303  return hr;
304  }
305 
306  // increments reference count
307  STDMETHOD_(ULONG, AddRef)() { return CXAPOBase::AddRef(); }
308 
309  // decrements reference count and deletes the object if the reference count falls to zero
310  STDMETHOD_(ULONG, Release)() { return CXAPOBase::Release(); }
311 
312  // IXAPOParameters methods:
313  // Sets effect-specific parameters.
314  // This method may only be called on the realtime audio processing thread.
315  STDMETHOD_(void, SetParameters) (_In_reads_bytes_(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize);
316 
317  // Gets effect-specific parameters.
318  // This method may block and should not be called from the realtime thread.
319  // Get the current parameters via BeginProcess.
320  STDMETHOD_(void, GetParameters) (_Out_writes_bytes_(ParameterByteSize) void* pParameters, UINT32 ParameterByteSize);
321 
322  // Called by SetParameters() to allow for user-defined parameter validation.
323  // SetParameters validates that ParameterByteSize == m_uParameterBlockByteSize
324  // so the user may assume/assert ParameterByteSize == m_uParameterBlockByteSize.
325  // This method should not block as it is called from the realtime thread.
326  virtual void OnSetParameters (_In_reads_bytes_(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize)
327  {
328  XAPOASSERT(m_uParameterBlockByteSize > 0);
329  XAPOASSERT(pParameters != NULL);
330  XAPOASSERT(ParameterByteSize == m_uParameterBlockByteSize);
331  }
332 
333  // Returns TRUE if SetParameters() has been called since the last processing pass.
334  // May only be used within the XAPO's IXAPO::Process implementation,
335  // before BeginProcess is called.
336  BOOL ParametersChanged ();
337 
338  // Returns latest process parameters.
339  // XAPOs must call this method within their IXAPO::Process
340  // implementation to access latest process parameters in threadsafe manner.
341  BYTE* BeginProcess ();
342 
343  // Notifies CXAPOParametersBase that the XAPO has finished accessing
344  // the latest process parameters.
345  // XAPOs must call this method within their IXAPO::Process
346  // implementation to access latest process parameters in threadsafe manner.
347  void EndProcess ();
348 };
349 
350 
351 #pragma pack(pop) // revert packing alignment
352 //---------------------------------<-EOF->----------------------------------//
typedef HRESULT(WINAPI *PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)(_In_ const D3D12_ROOT_SIGNATURE_DESC *pRootSignature
_Outptr_ IUnknown _In_reads_bytes_opt_(InitDataByteSize) const void *pInitData
#define NULL
Pointer to 0.
Definition: gctypes.h:65
float FLOAT32
Definition: xapobase.h:60
static INLINE ULONG Release(void *object)
Definition: dxgi_common.h:253
unsigned int BOOL
Definition: gctypes.h:51
uint32_t UINT32
Definition: coretypes.h:10
#define XAPOASSERT(exp)
Definition: xapobase.h:43
Definition: audiodefs.h:40
Definition: xapo.h:187