123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- /*-========================================================================-_
- | - XAPO - |
- | Copyright (c) Microsoft Corporation. All rights reserved. |
- |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
- |PROJECT: XAPO MODEL: Unmanaged User-mode |
- |VERSION: 1.0 EXCEPT: No Exceptions |
- |CLASS: N / A MINREQ: WinXP, Xbox360 |
- |BASE: N / A DIALECT: MSC++ 14.00 |
- |>------------------------------------------------------------------------<|
- | DUTY: XAPO base classes |
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
- NOTES:
- 1. See XAPO.h for the rules governing XAPO interface behaviour. */
- #pragma once
- //--------------<D-E-F-I-N-I-T-I-O-N-S>-------------------------------------//
- #include "XAPO.h"
- // default audio format ranges supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS.pFormat
- #define XAPOBASE_DEFAULT_FORMAT_TAG WAVE_FORMAT_IEEE_FLOAT // 32-bit float only, applies to WAVEFORMATEX.wFormatTag or WAVEFORMATEXTENSIBLE.SubFormat when used
- #define XAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS XAPO_MIN_CHANNELS // minimum channel count, applies to WAVEFORMATEX.nChannels
- #define XAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS XAPO_MAX_CHANNELS // maximum channel count, applies to WAVEFORMATEX.nChannels
- #define XAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE XAPO_MIN_FRAMERATE // minimum framerate, applies to WAVEFORMATEX.nSamplesPerSec
- #define XAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE XAPO_MAX_FRAMERATE // maximum framerate, applies to WAVEFORMATEX.nSamplesPerSec
- #define XAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE 32 // 32-bit float only, applies to WAVEFORMATEX.wBitsPerSample and WAVEFORMATEXTENSIBLE.wValidBitsPerSample when used
- // default XAPO property flags supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
- #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)
- // default number of input and output buffers supported, applies to XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
- #define XAPOBASE_DEFAULT_BUFFER_COUNT 1
- //--------------<M-A-C-R-O-S>-----------------------------------------------//
- // assertion
- #if !defined(XAPOASSERT)
- #if XAPODEBUG
- #define XAPOASSERT(exp) if (!(exp)) { OutputDebugStringA("XAPO ASSERT: " #exp ", {" __FUNCTION__ "}\n"); __debugbreak(); }
- #else
- #define XAPOASSERT(exp) __assume(exp)
- #endif
- #endif
- //--------------<D-A-T-A---T-Y-P-E-S>---------------------------------------//
- #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
- // primitive types
- typedef float FLOAT32; // 32-bit IEEE float
- ////
- // DESCRIPTION:
- // Default implementation of the IXAPO and IUnknown interfaces.
- // Provides overridable implementations for all methods save IXAPO::Process.
- ////
- class __declspec(novtable) CXAPOBase: public IXAPO {
- private:
- const XAPO_REGISTRATION_PROPERTIES* m_pRegistrationProperties; // pointer to registration properties of the XAPO, set via constructor
- void* m_pfnMatrixMixFunction; // optimal matrix function pointer, used for thru processing
- FLOAT32* m_pfl32MatrixCoefficients; // matrix coefficient table, used for thru processing
- UINT32 m_nSrcFormatType; // input format type, used for thru processing
- 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
- BOOL m_fIsLocked; // TRUE if XAPO locked via CXAPOBase.LockForProcess
- protected:
- LONG m_lReferenceCount; // COM reference count, must be aligned for atomic operations
- ////
- // DESCRIPTION:
- // Verifies an audio format falls within the default ranges supported.
- //
- // REMARKS:
- // If pFormat is unsupported, and fOverwrite is TRUE,
- // pFormat is overwritten with the nearest format supported.
- // Nearest meaning closest bit depth, framerate, and channel count,
- // in that order of importance.
- //
- // PARAMETERS:
- // pFormat - [in/out] audio format to examine
- // fOverwrite - [in] TRUE to overwrite pFormat if audio format unsupported
- //
- // RETURN VALUE:
- // COM error code, including:
- // S_OK - audio format supported, pFormat left untouched
- // XAPO_E_FORMAT_UNSUPPORTED - audio format unsupported, pFormat overwritten with nearest audio format supported if fOverwrite TRUE
- // E_INVALIDARG - audio format invalid, pFormat left untouched
- ////
- virtual HRESULT ValidateFormatDefault (__inout WAVEFORMATEX* pFormat, BOOL fOverwrite);
- ////
- // DESCRIPTION:
- // Verifies that an input/output format pair configuration is supported
- // with respect to the XAPO property flags.
- //
- // REMARKS:
- // If pRequestedFormat is unsupported, and fOverwrite is TRUE,
- // pRequestedFormat is overwritten with the nearest format supported.
- // Nearest meaning closest bit depth, framerate, and channel count,
- // in that order of importance.
- //
- // PARAMETERS:
- // pSupportedFormat - [in] audio format known to be supported
- // pRequestedFormat - [in/out] audio format to examine, must be WAVEFORMATEXTENSIBLE if fOverwrite TRUE
- // fOverwrite - [in] TRUE to overwrite pRequestedFormat if input/output configuration unsupported
- //
- // RETURN VALUE:
- // COM error code, including:
- // S_OK - input/output configuration supported, pRequestedFormat left untouched
- // XAPO_E_FORMAT_UNSUPPORTED - input/output configuration unsupported, pRequestedFormat overwritten with nearest audio format supported if fOverwrite TRUE
- // E_INVALIDARG - either audio format invalid, pRequestedFormat left untouched
- ////
- HRESULT ValidateFormatPair (const WAVEFORMATEX* pSupportedFormat, __inout WAVEFORMATEX* pRequestedFormat, BOOL fOverwrite);
- ////
- // DESCRIPTION:
- // This method may be called by an IXAPO::Process implementation
- // for thru processing. It copies/mixes data from source to
- // destination, making as few changes as possible to the audio data.
- //
- // REMARKS:
- // However, this method is capable of channel upmix/downmix and uses
- // the same matrix coefficient table used by windows Vista to do so.
- //
- // For in-place processing (input buffer == output buffer)
- // this method does nothing.
- //
- // This method should be called only if the XAPO is locked and
- // XAPO_FLAG_FRAMERATE_MUST_MATCH is used.
- //
- // PARAMETERS:
- // 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
- // pOutputBuffer - [out] output buffer, format must be FLOAT32
- // FrameCount - [in] number of frames to process
- // InputChannelCount - [in] number of input channels
- // OutputChannelCount - [in] number of output channels
- // MixWithOutput - [in] TRUE to mix with output, FALSE to overwrite output
- //
- // RETURN VALUE:
- // void
- ////
- void ProcessThru (__in void* pInputBuffer, __inout FLOAT32* pOutputBuffer, UINT32 FrameCount, WORD InputChannelCount, WORD OutputChannelCount, BOOL MixWithOutput);
- // accessors
- const XAPO_REGISTRATION_PROPERTIES* GetRegistrationPropertiesInternal () { return m_pRegistrationProperties; }
- BOOL IsLocked () { return m_fIsLocked; }
- public:
- CXAPOBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties);
- virtual ~CXAPOBase ();
- // IUnknown methods:
- // retrieves the requested interface pointer if supported
- STDMETHOD(QueryInterface) (REFIID riid, __deref_out_opt void** ppInterface)
- {
- XAPOASSERT(ppInterface != NULL);
- HRESULT hr = S_OK;
- if (riid == __uuidof(IXAPO)) {
- *ppInterface = static_cast<IXAPO*>(this);
- AddRef();
- } else if (riid == __uuidof(IUnknown)) {
- *ppInterface = static_cast<IUnknown*>(this);
- AddRef();
- } else {
- *ppInterface = NULL;
- hr = E_NOINTERFACE;
- }
- return hr;
- }
- // increments reference count
- STDMETHOD_(ULONG, AddRef) ()
- {
- return (ULONG)InterlockedIncrement(&m_lReferenceCount);
- }
- // decrements reference count and deletes the object if the reference count falls to zero
- STDMETHOD_(ULONG, Release) ()
- {
- ULONG uTmpReferenceCount = (ULONG)InterlockedDecrement(&m_lReferenceCount);
- if (uTmpReferenceCount == 0) {
- delete this;
- }
- return uTmpReferenceCount;
- }
- // IXAPO methods:
- // Allocates a copy of the registration properties of the XAPO.
- // This default implementation returns a copy of the registration
- // properties given to the constructor, allocated via XAPOAlloc.
- STDMETHOD(GetRegistrationProperties) (__deref_out XAPO_REGISTRATION_PROPERTIES** ppRegistrationProperties);
- // Queries if a specific input format is supported for a given output format.
- // This default implementation assumes only the format described by the
- // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
- STDMETHOD(IsInputFormatSupported) (const WAVEFORMATEX* pOutputFormat, const WAVEFORMATEX* pRequestedInputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedInputFormat);
- // Queries if a specific output format is supported for a given input format.
- // This default implementation assumes only the format described by the
- // XAPOBASE_DEFAULT_FORMAT values are supported for both input and output.
- STDMETHOD(IsOutputFormatSupported) (const WAVEFORMATEX* pInputFormat, const WAVEFORMATEX* pRequestedOutputFormat, __deref_opt_out WAVEFORMATEX** ppSupportedOutputFormat);
- // Performs any effect-specific initialization.
- // This default implementation is a no-op and only returns S_OK.
- STDMETHOD(Initialize) (__in_bcount_opt(DataByteSize) const void*, UINT32 DataByteSize)
- {
- UNREFERENCED_PARAMETER(DataByteSize);
- return S_OK;
- }
- // Resets variables dependent on frame history.
- // This default implementation is a no-op: this base class contains no
- // relevant state to reset.
- STDMETHOD_(void, Reset) () { return; }
- // Notifies XAPO of buffer formats Process() will be given.
- // This default implementation performs basic input/output format
- // validation against the XAPO's registration properties.
- // Derived XAPOs should call the base implementation first.
- 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);
- // Opposite of LockForProcess.
- // Derived XAPOs should call the base implementation first.
- STDMETHOD_(void, UnlockForProcess) ();
- // Returns the number of input frames required to generate the requested number of output frames.
- // By default, this method returns the same number of frames it was passed.
- STDMETHOD_(UINT32, CalcInputFrames) (UINT32 OutputFrameCount) { return OutputFrameCount; }
- // Returns the number of output frames generated for the requested number of input frames.
- // By default, this method returns the same number of frames it was passed.
- STDMETHOD_(UINT32, CalcOutputFrames) (UINT32 InputFrameCount) { return InputFrameCount; }
- };
- //--------------------------------------------------------------------------//
- ////
- // DESCRIPTION:
- // Extends CXAPOBase, providing a default implementation of the
- // IXAPOParameters interface with appropriate synchronization to
- // protect variables shared between IXAPOParameters::GetParameters
- // and IXAPOParameters::SetParameters/IXAPO::Process.
- //
- // This class is for parameter blocks whose size is larger than 4 bytes.
- // For smaller parameter blocks, use atomic operations directly
- // on the parameters for synchronization.
- ////
- class __declspec(novtable) CXAPOParametersBase: public CXAPOBase, public IXAPOParameters {
- private:
- BYTE* m_pParameterBlocks; // three contiguous process parameter blocks used for synchronization, user responsible for initialization of parameter blocks before IXAPO::Process/SetParameters/GetParameters called
- BYTE* m_pCurrentParameters; // pointer to current process parameters, must be aligned for atomic operations
- BYTE* m_pCurrentParametersInternal; // pointer to current process parameters (temp pointer read by SetParameters/BeginProcess/EndProcess)
- UINT32 m_uCurrentParametersIndex; // index of current process parameters
- UINT32 m_uParameterBlockByteSize; // size of a single parameter block in bytes, must be > 0
- BOOL m_fNewerResultsReady; // TRUE if there exists new processing results not yet picked up by GetParameters(), must be aligned for atomic operations
- BOOL m_fProducer; // IXAPO::Process produces data to be returned by GetParameters(); SetParameters() disallowed
- public:
- ////
- // PARAMETERS:
- // pRegistrationProperties - [in] registration properties of the XAPO
- // pParameterBlocks - [in] three contiguous process parameter blocks used for synchronization
- // uParameterBlockByteSize - [in] size of one of the parameter blocks, must be > 0
- // fProducer - [in] TRUE if IXAPO::Process produces data to be returned by GetParameters() (SetParameters() and ParametersChanged() disallowed)
- ////
- CXAPOParametersBase (const XAPO_REGISTRATION_PROPERTIES* pRegistrationProperties, BYTE* pParameterBlocks, UINT32 uParameterBlockByteSize, BOOL fProducer);
- virtual ~CXAPOParametersBase ();
- // IUnknown methods:
- // retrieves the requested interface pointer if supported
- STDMETHOD(QueryInterface) (REFIID riid, __deref_out_opt void** ppInterface)
- {
- XAPOASSERT(ppInterface != NULL);
- HRESULT hr = S_OK;
- if (riid == __uuidof(IXAPOParameters)) {
- *ppInterface = static_cast<IXAPOParameters*>(this);
- CXAPOBase::AddRef();
- } else {
- hr = CXAPOBase::QueryInterface(riid, ppInterface);
- }
- return hr;
- }
- // increments reference count
- STDMETHOD_(ULONG, AddRef)() { return CXAPOBase::AddRef(); }
- // decrements reference count and deletes the object if the reference count falls to zero
- STDMETHOD_(ULONG, Release)() { return CXAPOBase::Release(); }
- // IXAPOParameters methods:
- // Sets effect-specific parameters.
- // This method may only be called on the realtime audio processing thread.
- STDMETHOD_(void, SetParameters) (__in_bcount(ParameterByteSize) const void* pParameters, UINT32 ParameterByteSize);
- // Gets effect-specific parameters.
- // This method may block and should not be called from the realtime thread.
- // Get the current parameters via BeginProcess.
- STDMETHOD_(void, GetParameters) (__out_bcount(ParameterByteSize) void* pParameters, UINT32 ParameterByteSize);
- // Called by SetParameters() to allow for user-defined parameter validation.
- // SetParameters validates that ParameterByteSize == m_uParameterBlockByteSize
- // so the user may assume/assert ParameterByteSize == m_uParameterBlockByteSize.
- // This method should not block as it is called from the realtime thread.
- virtual void OnSetParameters (const void*, UINT32) { }
- // Returns TRUE if SetParameters() has been called since the last processing pass.
- // May only be used within the XAPO's IXAPO::Process implementation,
- // before BeginProcess is called.
- BOOL ParametersChanged ();
- // Returns latest process parameters.
- // XAPOs must call this method within their IXAPO::Process
- // implementation to access latest process parameters in threadsafe manner.
- BYTE* BeginProcess ();
- // Notifies CXAPOParametersBase that the XAPO has finished accessing
- // the latest process parameters.
- // XAPOs must call this method within their IXAPO::Process
- // implementation to access latest process parameters in threadsafe manner.
- void EndProcess ();
- };
- #pragma pack(pop) // revert packing alignment
- //---------------------------------<-EOF->----------------------------------//
|