/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::GetSupportedDeviceFormats 
 
Decscription:

    GetSupportedDeviceFormats get the complete format list supported by the hw Audio Engine

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _Out_ pFormat: a buffer pointer for receiving the supported device formats
		_In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::GetSupportedDeviceFormats(_In_  ULONG _ulNodeId, _Out_ KSMULTIPLE_ITEM* _pFormat, _In_ ULONG _ulBufferSize)
{
    PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pDeviceFormats;
    ULONG cDeviceFormats;
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    PAGED_CODE ();

    ASSERT(_pFormat);

    DPF_ENTER(("[CMiniportWaveRT::GetSupportedDeviceFormats]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    cDeviceFormats = GetAudioEngineSupportedDeviceFormats(&pDeviceFormats);

    KSMULTIPLE_ITEM *pKsMulti = static_cast<KSMULTIPLE_ITEM*>(_pFormat);
    pKsMulti->Size = sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE) * cDeviceFormats;
    pKsMulti->Count = cDeviceFormats;

    IF_TRUE_ACTION_JUMP(_ulBufferSize < pKsMulti->Size, ntStatus = STATUS_BUFFER_TOO_SMALL, Exit);

    RtlCopyMemory((PVOID)(pKsMulti + 1), pDeviceFormats,
        sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE) * cDeviceFormats);

    ntStatus = STATUS_SUCCESS;

Exit:    
    return ntStatus;
}
Exemple #2
0
// ----------------------------------------------------------------------
// Function:
//      CPartsList::GetPart
//
// Description:
//      Returns the nIndex-th item in the list of IParts
//
// Parameters:
//      nIndex - [in] index of the part to access
//      uMsg - [out] the part at the specified index
//
// Return:
//      S_OK if successful
//
// ----------------------------------------------------------------------
_Use_decl_annotations_
STDMETHODIMP CPartsList::GetPart
(
    UINT nIndex,
    IPart** ppPart
)
{
    HRESULT hr;
    IPart*  pIPart = NULL;

    // Protect m_lstParts access
    m_CritSection.Enter();

    IF_TRUE_ACTION_JUMP((ppPart == NULL), hr = E_POINTER, Exit);

    *ppPart = NULL;

    IF_TRUE_ACTION_JUMP((nIndex >= m_lstParts.GetCount()), hr = E_INVALIDARG, Exit);

    IF_TRUE_ACTION_JUMP((!m_lstParts.GetAt(nIndex, &pIPart)), hr = E_NOTFOUND, Exit);

    // Take care of AddRef and ensure correct interface in one shot
    hr = pIPart->QueryInterface(__uuidof(IPart), reinterpret_cast<void**>(ppPart));
    IF_FAILED_JUMP(hr, Exit);

Exit:
    m_CritSection.Leave();

    return hr;
}
Exemple #3
0
//-------------------------------------------------------------------------
// Description:
//
//  Implementation of IAudioSystemEffectsCustomFormats::GetFormatRepresentation
//
// Parameters:
//
//      nFormat - [in] which format is being requested
//      ppwstrFormatRep - [in] address of a variable that will receive a ptr 
//                             to a new string description of the requested format
//
// Return values:
//
//      S_OK            Success
//      E_INVALIDARG    nFormat is out of range
//      E_POINTER       Null pointer passed
//
// Remarks:
//
STDMETHODIMP CSwapAPOGFX::GetFormatRepresentation
(
    UINT                nFormat,
    _Outptr_ LPWSTR* ppwstrFormatRep
)
{
    HRESULT hr;
    size_t  cbRep;
    LPWSTR  pwstrLocal;

    IF_TRUE_ACTION_JUMP((nFormat >= _cCustomFormats), hr = E_INVALIDARG, Exit);
    IF_TRUE_ACTION_JUMP((ppwstrFormatRep == NULL), hr = E_POINTER, Exit);

    cbRep = (wcslen(_rgCustomFormats[nFormat].pwszRep) + 1) * sizeof(WCHAR);

    pwstrLocal = (LPWSTR)CoTaskMemAlloc(cbRep);
    IF_TRUE_ACTION_JUMP((pwstrLocal == NULL), hr = E_OUTOFMEMORY, Exit);

    hr = StringCbCopyW(pwstrLocal, cbRep, _rgCustomFormats[nFormat].pwszRep);
    if (FAILED(hr))
    {
        CoTaskMemFree(pwstrLocal);
    }
    else
    {
        *ppwstrFormatRep = pwstrLocal;
    }

Exit:
    return hr;
}
Exemple #4
0
HRESULT CSwapAPOLFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
{
    HRESULT                         hr = S_OK;
    PROPVARIANT                     var;

    IF_TRUE_ACTION_JUMP( ((NULL == pbyData) && (0 != cbDataSize)), hr = E_INVALIDARG, Exit);
    IF_TRUE_ACTION_JUMP( ((NULL != pbyData) && (0 == cbDataSize)), hr = E_POINTER, Exit);
    IF_TRUE_ACTION_JUMP( (cbDataSize != sizeof(APOInitSystemEffects) ), hr = E_INVALIDARG, Exit);

    APOInitSystemEffects* papoSysFxInit = (APOInitSystemEffects*)pbyData;

    //
    //  Store locally for later reference
    //
    m_spAPOSystemEffectsProperties = papoSysFxInit->pAPOSystemEffectsProperties;

    //
    //  Get the current value
    //
    PropVariantInit(&var);

    if (m_spAPOSystemEffectsProperties != NULL)
    {
        // Get the state of whether channel swap LFX is enabled or not
        hr = m_spAPOSystemEffectsProperties->GetValue(PKEY_Endpoint_Enable_Channel_Swap_LFX, &var);

        if (SUCCEEDED(hr) && (var.vt == VT_UI4))
        {
            if (var.ulVal == 0L)
            {
                m_fEnableSwapLFX = FALSE;
            }
            else
            {
                m_fEnableSwapLFX = TRUE;
            }
        }
        else
        {
            PropVariantClear(&var);
        }
    }

    //
    //  Register for notification of registry updates
    //
    hr = m_spEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));
    IF_FAILED_JUMP(hr, Exit);

    hr = m_spEnumerator->RegisterEndpointNotificationCallback(this);
    IF_FAILED_JUMP(hr, Exit);

     m_bIsInitialized = true;


Exit:
    return hr;
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::GetDeviceAttributeSteppings 
 
Decscription:

    When handling volume, mute, and meter related KS properties, Portcls calls 
    this method, inside its property handlers, to know the property stepping information for the 
    corresponding KS property.

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _In_ _targetType:  the query target (volume. mute, or peak meter)
		_Out_ _pKsPropMembHead: a pointer to a PKSPROPERTY_STEPPING_LONG variable for receiving returned channel count information
        _In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by _pKsPropMembHead

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
NTSTATUS CMiniportWaveRT::GetDeviceAttributeSteppings(_In_  ULONG _ulNodeId, _In_  eChannelTargetType _targetType, _Out_ PKSPROPERTY_STEPPING_LONG _pKsPropMembHead, _In_  UINT32 _ui32DataSize)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE ();

    DPF_ENTER(("[CMiniportWaveRT::GetDeviceAttributeSteppings]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    switch (_targetType)
    {
        case eVolumeAttribute:
             ntStatus = GetVolumeSteppings(_pKsPropMembHead, _ui32DataSize);;
             break;
        case eMuteAttribute:
             ntStatus = GetMuteSteppings(_pKsPropMembHead, _ui32DataSize);;
             break;
        case ePeakMeterAttribute:
             ntStatus = GetPeakMeterSteppings(_pKsPropMembHead, _ui32DataSize);;
             break;
        default:
            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
            break;
    }
Exit:
     return ntStatus;
}
Exemple #6
0
// ----------------------------------------------------------------------------
// Function:
//      CSwapPropPage::SetSwapGFXState
//
// Description:
//      Enable or disable channel swap GFX
//
// Return values:
//      S_OK if successful
// ----------------------------------------------------------------------------
HRESULT CSwapPropPage::SetSwapGFXState()
{
    HRESULT                 hr = S_OK;
    PROPVARIANT             var;

    IF_TRUE_ACTION_JUMP((m_pAudioFXExtParams == NULL), hr = E_POINTER, Exit);

    PropVariantInit(&var);

    if (m_pAudioFXExtParams->pFxProperties != NULL)
    {
        var.vt = VT_UI4;

        if (m_fEnableSwapGFX)
        {
            var.ulVal = 1L;
        }
        else
        {
            var.ulVal = 0L;
        }

        // Enable or disable channel swap GFX
        hr = m_pAudioFXExtParams->pFxProperties->SetValue(PKEY_Endpoint_Enable_Channel_Swap_GFX, var);
    }

Exit:
    return(hr);
}
NTSTATUS CMiniportWaveRT::GetDeviceChannelCount
(
        _In_  ULONG					_ulNodeId,
        _In_  eChannelTargetType	_targetType,
		_Out_  UINT32				*_pulChannelCount
)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE ();
    ASSERT(_pulChannelCount);

    DPF_ENTER(("[CMiniportWaveRT::GetChannelCount]"));

    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    switch (_targetType)
    {
        case eVolumeAttribute:
             ntStatus = GetVolumeChannelCount(_pulChannelCount);
             break;
        case eMuteAttribute:
             ntStatus = GetMuteChannelCount(_pulChannelCount);
             break;
        case ePeakMeterAttribute:
             ntStatus = GetPeakMeterChannelCount(_pulChannelCount);
             break;
        default:
            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
            break;
    }
Exit:
    return ntStatus;
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::SetDeviceFormat 
 
Decscription:

    GetDeviceFormat set the current device format to be used by the HW Audio Engine

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _Out_ pFormat: a buffer pointer with the device format to be set to the hw Audio Engine
		_In_ ulBufferSize: a pointer to a ULONG variable that has the size of the buffer pointed by pFormat

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks
  Setting the device format of a HW Audio Engine could potential impact the mix format inside the HD Audio Engine.
The driver might need to add appropriate src/format converter according or change mix format.

-------------------------------------------------------------------------------------------------------------------------*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::SetDeviceFormat(_In_  ULONG _ulNodeId, _In_ KSDATAFORMAT_WAVEFORMATEX *_pFormat, _In_ ULONG _ulBufferSize)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    PAGED_CODE ();

    ASSERT (_pFormat);

    DPF_ENTER(("[CMiniportWaveRT::SetDeviceFormat]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);
    IF_TRUE_ACTION_JUMP(_ulBufferSize < sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE), ntStatus = STATUS_BUFFER_TOO_SMALL, Exit);

    RtlCopyMemory((PVOID)m_pDeviceFormat, (PVOID)_pFormat, sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE));
    ntStatus = STATUS_SUCCESS;

Exit:    
    return ntStatus;
}
Exemple #9
0
//-------------------------------------------------------------------------
// Description:
//
//  Implementation of IAudioSystemEffectsCustomFormats::GetFormat
//
// Parameters:
//
//      nFormat - [in] which format is being requested
//      IAudioMediaType - [in] address of a variable that will receive a ptr 
//                             to a new IAudioMediaType object
//
// Return values:
//
//      S_OK            Success
//      E_INVALIDARG    nFormat is out of range
//      E_POINTER       Null pointer passed
//
// Remarks:
//
STDMETHODIMP CSwapAPOGFX::GetFormat
(
    UINT              nFormat, 
    IAudioMediaType** ppFormat
)
{
    HRESULT hr;

    IF_TRUE_ACTION_JUMP((nFormat >= _cCustomFormats), hr = E_INVALIDARG, Exit);
    IF_TRUE_ACTION_JUMP((ppFormat == NULL), hr = E_POINTER, Exit);

    *ppFormat = NULL; 

    hr = CreateAudioMediaType(  (const WAVEFORMATEX*)&_rgCustomFormats[nFormat].wfxFmt, 
                                sizeof(_rgCustomFormats[nFormat].wfxFmt),
                                ppFormat);

Exit:
    return hr;
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::GetDeviceChannelPeakMeter 
 
Decscription:

    When handling GET peak meter KS property for the device, Portcls calls 
    this method, inside its property handlers, to get the current setting on the specific channel.

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _In_ _uiChannel:  the target channel for this GET volume operation
        _Out_ _pPeakMeterValue: a pointer to a LONG variable for receiving returned information

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::GetDeviceChannelPeakMeter(_In_  ULONG _ulNodeId, _In_ UINT32 _uiChannel, _Out_  LONG  *_pPeakMeterValue)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    PAGED_CODE ();

    DPF_ENTER(("[CMiniportWaveRT::GetDeviceChannelPeakMeter]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);
    ntStatus = GetChannelPeakMeter(_uiChannel, _pPeakMeterValue);

Exit:
    return ntStatus;
}
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::GetDeviceFormat(_In_ ULONG _ulNodeId, _Out_ KSDATAFORMAT_WAVEFORMATEX *_pFormat, _In_ ULONG _ulBufferSize)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    PAGED_CODE ();

    ASSERT (_pFormat);

    DPF_ENTER(("[CMiniportWaveRT::GetDeviceFormat]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);
    IF_TRUE_ACTION_JUMP(_ulBufferSize < sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE), ntStatus = STATUS_BUFFER_TOO_SMALL, Exit);
#pragma warning(push)
        // IMiniportAudioEngineNode::GetDeviceFormat's annotation on _pFormat requires it to be KSDATAFORMAT_WAVEFORMATEX.  However,
        // this implementation here will always be called by our own code with _pFormat to be KSDATAFORMAT_WAVEFORMATEXTENSIBLE,
        // so there should be no buffer overrun; also the IF_TRUE_ACTION_JUMP above also help to avoid buffer overrun. 
#pragma warning(disable:6386)
    RtlCopyMemory((PVOID)_pFormat, (PVOID)m_pDeviceFormat, sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE));
#pragma warning (pop)
    ntStatus = STATUS_SUCCESS;

Exit:    
    return ntStatus;
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::SetDeviceChannelMute 
 
Decscription:

    When handling SET mute KS property for the device, Portcls calls 
    this method, inside its property handlers, to set the current setting on the specific channel.

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _In_ _uiChannel:  the target channel for this GET volume operation
		_In_ _bMute: volume value to set 

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
NTSTATUS CMiniportWaveRT::SetDeviceChannelMute(_In_  ULONG _ulNodeId, _In_ UINT32 _uiChannel, _In_  BOOL  _bMute)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE ();

    DPF_ENTER(("[CMiniportWaveRT::SetEndpointChannelMute]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    ntStatus = SetChannelMute(_uiChannel, _bMute);

Exit:
    return ntStatus;
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::SetDeviceChannelVolume 
 
Decscription:

    When handling SET volume KS property for the device, Portcls calls 
    this method, inside its property handlers, to set the current setting on the specific channel.

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _In_ _uiChannel:  the target channel for this GET volume operation
		_In_ _Volume: volume value to set 

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::SetDeviceChannelVolume(_In_  ULONG _ulNodeId, _In_ UINT32 _uiChannel, _In_  LONG  _Volume)
{
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE ();

    DPF_ENTER(("[CMiniportWaveRT::SetEndpointChannelVolume]"));
    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    // Snap the volume level to our range of steppings.
    LONG lVolume = VOLUME_NORMALIZE_IN_RANGE(_Volume); 

    ntStatus = SetChannelVolume(_uiChannel, lVolume);

Exit:
    return ntStatus;
}
//-------------------------------------------------------------------------
// Description:
//
//  Report delay added by the APO between samples given on input
//  and samples given on output.
//
// Parameters:
//
//      pTime                       - [out] hundreds-of-nanoseconds of delay added
//
// Return values:
//
//      S_OK on success, a failure code on failure
STDMETHODIMP CSwapAPOMFX::GetLatency(HNSTIME* pTime)  
{  
    ASSERT_NONREALTIME();  
    HRESULT hr = S_OK;  
  
    IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit);  
  
    if (IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW))
    {
        *pTime = 0;
    }
    else
    {
        *pTime = (m_fEnableDelayMFX ? HNS_DELAY : 0);
    }
  
Exit:  
    return hr;  
}
// ----------------------------------------------------------------------------
// Function:
//      CSwapPropPage::GetDeviceFriendlyName
//
// Description:
//      Retrieves the endpoint's friendly name
//
// Parameters:
//      ppNameOut - [out] The friendly name of the endpoint
//
// Return values:
//      S_OK if successful
// ----------------------------------------------------------------------------
HRESULT CSwapPropPage::GetDeviceFriendlyName
(
    _Outptr_result_maybenull_ LPWSTR* ppNameOut
)
{
    CComPtr<IMMDeviceEnumerator>    spEnumerator;
    CComPtr<IPropertyStore>         spProperties;
    CComPtr<IMMDevice>              spMMDevice;
    HRESULT                         hr = S_OK;
    PROPVARIANT                     var;

    IF_TRUE_ACTION_JUMP((ppNameOut == NULL), hr = E_POINTER, Exit);

    *ppNameOut = NULL;

    // Create device enumerator and get IMMDevice from the device ID
    hr = spEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));
    IF_FAILED_JUMP(hr, Exit);

    hr = spEnumerator->GetDevice(m_pAudioFXExtParams->pwstrEndpointID, &spMMDevice);
    IF_FAILED_JUMP(hr, Exit);

    // Open the PropertyStore for read access
    hr = spMMDevice->OpenPropertyStore(STGM_READ, &spProperties);
    IF_FAILED_JUMP(hr, Exit);

    PropVariantInit(&var);

    // Retrieve the friendly name of the endpoint
    hr = spProperties->GetValue(PKEY_Device_FriendlyName, &var);
    if (SUCCEEDED(hr) && (var.vt == VT_LPWSTR))
    {
        *ppNameOut = var.pwszVal;
    }
    else
    {
        PropVariantClear(&var);
    }

Exit:
    return(hr);
}
/*-----------------------------------------------------------------------------
IMiniportAudioEngineNode::GetEngineFormatSize 
 
Decscription:

    When handling GetMixFormat, DeviceFormat, or SupportDeviceFormatsList, Portcls calls 
    this method to know the correct data size to allocate for the receiving the corresponding
    format information.

Parameters:

        _In_ _ulNodeId: node id for the target audio engine node
        _In_ eEngineFormatType: format target to indicate which format size is being asked
		_Out_ pulFormatSize: a pointer to a ULONG variable for receiving returned szize information

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
NTSTATUS CMiniportWaveRT::GetEngineFormatSize
(
    _In_    ULONG               _ulNodeId,
    _In_    eEngineFormatType   _formatType,
    _Out_   ULONG               *_pulFormatSize
)
{
    PAGED_CODE ();
    NTSTATUS ntStatus = STATUS_SUCCESS;

    DPF_ENTER(("[CMiniportWaveRT::GetEngineFormatSize]"));
    ASSERT (_pulFormatSize);

    IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);

    switch (_formatType)
    {
        case eMixFormat:
            DPF_ENTER(("[eMixFormat]"));
            *_pulFormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE);
            break;
        case eDeviceFormat:
            DPF_ENTER(("[eDeviceFormat]"));
            *_pulFormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE);
            break;
        case eSupportedDeviceFormats:
            DPF_ENTER(("[eSupportedDeviceFormats]"));
            *_pulFormatSize = sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE) * GetAudioEngineSupportedDeviceFormats(NULL);
            break;
        default:
            ntStatus = STATUS_INVALID_PARAMETER;
            break;
    }
Exit:
    return ntStatus;
}
Exemple #17
0
HRESULT CSwapAPOGFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
{
    HRESULT		        hr = S_OK;
    GUID                        processingMode;

    IF_TRUE_ACTION_JUMP( ((NULL == pbyData) && (0 != cbDataSize)), hr = E_INVALIDARG, Exit);
    IF_TRUE_ACTION_JUMP( ((NULL != pbyData) && (0 == cbDataSize)), hr = E_INVALIDARG, Exit);

    if (cbDataSize == sizeof(APOInitSystemEffects2))
    {
        //
        // Initialize for mode-specific signal processing
        //
        APOInitSystemEffects2* papoSysFxInit2 = (APOInitSystemEffects2*)pbyData;

        // Save reference to the effects property store. This saves effects settings
        // and is the communication medium between this APO and any associated UI.
        m_spAPOSystemEffectsProperties = papoSysFxInit2->pAPOSystemEffectsProperties;

        // Windows should pass a valid collection.
        ATLASSERT(papoSysFxInit2->pDeviceCollection != nullptr);
        IF_TRUE_ACTION_JUMP(papoSysFxInit2->pDeviceCollection == nullptr, hr = E_INVALIDARG, Exit);

        // Save the processing mode being initialized.
        processingMode = papoSysFxInit2->AudioProcessingMode;

        // There is information in the APOInitSystemEffects2 structure that could help facilitate 
        // proprietary communication between an APO instance and the KS pin that the APO is initialized on
        // Eg, in the case that an APO is implemented as an effect proxy for the effect processing hosted inside
        // an driver (either host CPU based or offload DSP based), the example below uses a combination of 
        // IDeviceTopology, IConnector, and IKsControl interfaces to communicate with the underlying audio driver. 
        // the following following routine demonstrates how to implement how to communicate to an audio driver from a APO.
        ProprietaryCommunicationWithDriver(papoSysFxInit2);
    }
    else if (cbDataSize == sizeof(APOInitSystemEffects))
    {
        //
        // Initialize for default signal processing
        //
        APOInitSystemEffects* papoSysFxInit = (APOInitSystemEffects*)pbyData;

        // Save reference to the effects property store. This saves effects settings
        // and is the communication medium between this APO and any associated UI.
        m_spAPOSystemEffectsProperties = papoSysFxInit->pAPOSystemEffectsProperties;

        // Assume default processing mode
        processingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT;
    }
    else
    {
        // Invalid initialization size
        hr = E_INVALIDARG;
        goto Exit;
    }

    // Validate then save the processing mode. Note an endpoint effects APO
    // does not depend on the mode. Windows sets the APOInitSystemEffects2
    // AudioProcessingMode member to GUID_NULL for an endpoint effects APO.
    IF_TRUE_ACTION_JUMP( (processingMode != AUDIO_SIGNALPROCESSINGMODE_DEFAULT && processingMode != AUDIO_SIGNALPROCESSINGMODE_RAW), hr = E_INVALIDARG, Exit);
    m_AudioProcessingMode = processingMode;

    //
    // An APO that implements signal processing more complex than this sample
    // would configure its processing for the processingMode determined above.
    // If necessary, the APO would also use the IDeviceTopology and IConnector
    // interfaces retrieved above to communicate with its counterpart audio
    // driver to configure any additional signal processing in the driver and
    // associated hardware.
    //

    //
    //  Get current effects settings
    //
    if (m_spAPOSystemEffectsProperties != NULL)
    {
        m_fEnableSwapGFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Channel_Swap_GFX, m_AudioProcessingMode);
    }

    //
    //  Register for notification of registry updates
    //
    hr = m_spEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));
    IF_FAILED_JUMP(hr, Exit);

    hr = m_spEnumerator->RegisterEndpointNotificationCallback(this);
    IF_FAILED_JUMP(hr, Exit);

    m_bIsInitialized = true;
Exit:
    return hr;
}