/*-----------------------------------------------------------------------------
IMiniportStreamAudioEngineNode::SetStreamChannelVolume 
 
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_ Channel:  the target channel for this GET volume operation
        _In_ TargetVolume: volume value to set 
        _In_ CurveType: type of curve to apply to the ramp
        _In_ CurveDuration: amount of time in hns over which to ramp the volume

Return Value:

   Appropriate NTSTATUS code

Called at PASSIVE_LEVEL

Remarks

-------------------------------------------------------------------------------------------------------------------------*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveRTStream::SetStreamChannelVolume
(
    _In_ UINT32             Channel,
    _In_ LONG	            TargetVolume,
    _In_ AUDIO_CURVE_TYPE   CurveType,
    _In_ ULONGLONG          CurveDuration
)
{
    UNREFERENCED_PARAMETER(CurveType);
    UNREFERENCED_PARAMETER(CurveDuration);
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

    PAGED_CODE ();

    DPF_ENTER(("[CMiniportWaveRTStream::SetStreamChannelVolume]"));

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

    // If Channel is ALL_CHANNELS_ID, then set the level on all channels
    if ( ALL_CHANNELS_ID == Channel )
    {
        for (UINT32 i = 0; i < m_pWfExt->Format.nChannels; i++)
        {
            ntStatus = SetChannelVolume(i, lVolume);
        }
    }
    else
    {
        ntStatus = SetChannelVolume(Channel, lVolume);
    }

    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;
}
Ejemplo n.º 3
0
NTSTATUS
PropertyHandler_Volume
(
    _In_  PADAPTERCOMMON        AdapterCommon,
    _In_  PPCPROPERTY_REQUEST   PropertyRequest,
    _In_  ULONG                 MaxChannels
)
/*++

Routine Description:

  Property handler for KSPROPERTY_AUDIO_VOLUMELEVEL

Arguments:

  AdapterCommon - interface to the common adapter object.
  
  PropertyRequest - property request structure.

  MaxChannels - # of supported channels.

Return Value:

  NT status code.

--*/
{
    PAGED_CODE();

    DPF_ENTER(("[%s]",__FUNCTION__));

    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    ULONG    ulChannel;
    PLONG    plVolume;

    if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
    {
        ntStatus = PropertyHandler_BasicSupportVolume(
                            PropertyRequest,
                            MaxChannels);
    }
    else
    {
        ntStatus = 
            ValidatePropertyParams
            (
                PropertyRequest, 
                sizeof(LONG),    // volume value is a LONG
                sizeof(ULONG)    // instance is the channel number
            );
        if (NT_SUCCESS(ntStatus))
        {
            ulChannel = * (PULONG (PropertyRequest->Instance));
            plVolume  = PLONG (PropertyRequest->Value);

            if (ulChannel >= MaxChannels &&
                ulChannel != ALL_CHANNELS_ID)
            {
               ntStatus = STATUS_INVALID_PARAMETER;
            }
            else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
            {
                *plVolume = 
                    AdapterCommon->MixerVolumeRead
                    (
                        PropertyRequest->Node, 
                        ulChannel == ALL_CHANNELS_ID ? 0 : ulChannel
                    );
                PropertyRequest->ValueSize = sizeof(ULONG);                
            }
            else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
            {
                if (ALL_CHANNELS_ID == ulChannel)
                {
                    for (ULONG i=0; i<ulChannel; ++i)
                    {
                        AdapterCommon->MixerVolumeWrite
                        (
                            PropertyRequest->Node, 
                            i, 
                            VOLUME_NORMALIZE_IN_RANGE(*plVolume)
                        );
                    }
                }
                else 
                {
                    AdapterCommon->MixerVolumeWrite
                    (
                        PropertyRequest->Node, 
                        ulChannel, 
                        VOLUME_NORMALIZE_IN_RANGE(*plVolume)
                    );
                }
            }
        }

        if (!NT_SUCCESS(ntStatus))
        {
            DPF(D_TERSE, ("[%s - ntStatus=0x%08x]",__FUNCTION__,ntStatus));
        }
    }

    return ntStatus;
} // PropertyHandlerVolume