⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************

    AVStream Filter-Centric Sample

    Copyright (c) 1999 - 2001, Microsoft Corporation

    File:

        audio.cpp

    Abstract:

        This file contains the audio capture pin implementation.

    History:

        created 6/28/01

**************************************************************************/

#include "avssamp.h"

/**************************************************************************

    PAGED CODE

**************************************************************************/

#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA


NTSTATUS
CAudioCapturePin::
DispatchCreate (
    IN PKSPIN Pin,
    IN PIRP Irp
    )

/*++

Routine Description:

    Create a new audio capture pin.  This is the creation dispatch for
    the audio capture pin.

Arguments:

    Pin -
        The pin being created

    Irp -
        The creation Irp

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    CAudioCapturePin *CapPin = new (NonPagedPool) CAudioCapturePin (Pin);
    CCapturePin *BasePin = static_cast <CCapturePin *> (CapPin);

    if (!CapPin) {
        //
        // Return failure if we couldn't create the pin.
        //
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {
        //
        // Add the item to the object bag if we we were successful. 
        // Whenever the pin closes, the bag is cleaned up and we will be
        // freed.
        //
        Status = KsAddItemToObjectBag (
            Pin -> Bag,
            reinterpret_cast <PVOID> (BasePin),
            reinterpret_cast <PFNKSFREE> (CCapturePin::BagCleanup)
            );

        if (!NT_SUCCESS (Status)) {
            delete CapPin;
        } else {
            Pin -> Context = reinterpret_cast <PVOID> (BasePin);
        }

    }

    return Status;

}

/*************************************************/


NTSTATUS
CAudioCapturePin::
Acquire (
    IN KSSTATE FromState
    )

/*++

Routine Description:

    Called when the pin transitions into acquire, this gets and releases
    our hold on the wave object we use to synthesize audio streams.

Arguments:

    FromState -
        The state the pin is transitioning away from

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    NTSTATUS Status = STATUS_SUCCESS;

    if (FromState == KSSTATE_STOP) {
        //
        // On the transition into acquire from stop, get ahold of the
        // wave object we're synthesizing from.
        //
        m_WaveObject = m_ParentFilter -> GetWaveObject ();
        ASSERT (m_WaveObject);

        //
        // There must be a wave object or something is really wrong.
        //
        if (!m_WaveObject) {
            Status = STATUS_INTERNAL_ERROR;
        } else {
            m_WaveObject -> Reset ();
        }

    } else {
        //
        // Ensure we hold no reference on the wave object.
        //
        m_WaveObject = NULL;

    }

    return Status;
            
}

/*************************************************/


NTSTATUS
CAudioCapturePin::
IntersectHandler (
    IN PKSFILTER Filter,
    IN PIRP Irp,
    IN PKSP_PIN PinInstance,
    IN PKSDATARANGE CallerDataRange,
    IN PKSDATARANGE DescriptorDataRange,
    IN ULONG BufferSize,
    OUT PVOID Data OPTIONAL,
    OUT PULONG DataSize
    )

/*++

Routine Description:

    The intersect handler for the audio capture pin.  This is really quite
    simple because the audio pin only exposes the number of channels,
    sampling frequency, etc...  that the wave file it is synthesizing from
    contains.

Arguments:

    Filter -
        Contains a void pointer to the  filter structure.

    Irp -
        Contains a pointer to the data intersection property request.

    PinInstance -
        Contains a pointer to a structure indicating the pin in question.

    CallerDataRange -
        Contains a pointer to one of the data ranges supplied by the client
        in the data intersection request.  The format type, subtype and
        specifier are compatible with the DescriptorDataRange.

    DescriptorDataRange -
        Contains a pointer to one of the data ranges from the pin descriptor
        for the pin in question.  The format type, subtype and specifier are
        compatible with the CallerDataRange.

    BufferSize -
        Contains the size in bytes of the buffer pointed to by the Data
        argument.  For size queries, this value will be zero.

    Data -
        Optionally contains a pointer to the buffer to contain the data 
        format structure representing the best format in the intersection 
        of the two data ranges.  For size queries, this pointer will be 
        NULL.

    DataSize -
        Contains a pointer to the location at which to deposit the size 
        of the data format.  This information is supplied by the function 
        when the format is actually delivered and in response to size 
        queries.

Return Value:

    STATUS_SUCCESS if there is an intersection and it fits in the supplied
    buffer, STATUS_BUFFER_OVERFLOW for successful size queries, 
    STATUS_NO_MATCH if the intersection is empty, or 
    STATUS_BUFFER_TOO_SMALL if the supplied buffer is too small.

--*/


{
    
    PAGED_CODE();

    //
    // Verify that the inpassed range is valid size. 
    //
    if (CallerDataRange -> FormatSize < sizeof (KSDATARANGE_AUDIO)) {
        return STATUS_NO_MATCH;
    }

    //
    // Because the only range we expose is such that it will match
    // KSDATARANGE_AUDIO, it is safe to interpret the data structures as
    // KSDATARANGE_AUDIO.  This is due to the fact that AVStream will have
    // prematched the GUIDs for us.
    //
    PKSDATARANGE_AUDIO CallerAudioRange =
        reinterpret_cast <PKSDATARANGE_AUDIO> (CallerDataRange);

    PKSDATARANGE_AUDIO DescriptorAudioRange =
        reinterpret_cast <PKSDATARANGE_AUDIO> (DescriptorDataRange);

    //
    // We are returning a KSDATAFORMAT_WAVEFORMATEX.  Specify such if a size
    // query happens.
    //
    if (BufferSize == 0) {
        *DataSize = sizeof (KSDATAFORMAT_WAVEFORMATEX);
        return STATUS_BUFFER_OVERFLOW;
    }

    if (BufferSize < sizeof (KSDATAFORMAT_WAVEFORMATEX)) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    //
    // Match the blocks.  We only support one format (not really a range), so
    // this intersection aught to be really simple.  It's more of a check
    // if the format we are going to use intersects somewhere in 
    // CallerAudioRange.
    //
    if (DescriptorAudioRange -> MaximumChannels > 
            CallerAudioRange -> MaximumChannels ||
        DescriptorAudioRange -> MinimumBitsPerSample <
            CallerAudioRange -> MinimumBitsPerSample ||
        DescriptorAudioRange -> MinimumBitsPerSample >
            CallerAudioRange -> MaximumBitsPerSample ||
        DescriptorAudioRange -> MinimumSampleFrequency <
            CallerAudioRange -> MinimumSampleFrequency ||
        DescriptorAudioRange -> MinimumSampleFrequency >
            CallerAudioRange -> MaximumSampleFrequency) {

        //
        // If the descriptor's "range" (more of a single format specified
        // in a range) doesn't intersect the caller's, no match the call.
        //
        *DataSize = sizeof (KSDATAFORMAT_WAVEFORMATEX);
        return STATUS_NO_MATCH;

    }

    //
    // Build the format.
    //
    PKSDATAFORMAT_WAVEFORMATEX WaveFormat =
        reinterpret_cast <PKSDATAFORMAT_WAVEFORMATEX> (Data);

    RtlCopyMemory (
        &WaveFormat -> DataFormat,
        &DescriptorAudioRange -> DataRange,
        sizeof (KSDATAFORMAT)
        );

    WaveFormat -> WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
    WaveFormat -> WaveFormatEx.nChannels = 
        (WORD)DescriptorAudioRange -> MaximumChannels;
    WaveFormat -> WaveFormatEx.nSamplesPerSec =
        DescriptorAudioRange -> MaximumSampleFrequency;
    WaveFormat -> WaveFormatEx.wBitsPerSample =
        (WORD)DescriptorAudioRange -> MaximumBitsPerSample;
    WaveFormat -> WaveFormatEx.nBlockAlign =
        (WaveFormat -> WaveFormatEx.wBitsPerSample / 8) *
        WaveFormat -> WaveFormatEx.nChannels;
    WaveFormat -> WaveFormatEx.nAvgBytesPerSec =
        WaveFormat -> WaveFormatEx.nBlockAlign *
        WaveFormat -> WaveFormatEx.nSamplesPerSec;
    WaveFormat -> WaveFormatEx.cbSize = 0;
    WaveFormat -> DataFormat.SampleSize = 
        WaveFormat -> WaveFormatEx.nBlockAlign;

    *DataSize = sizeof (KSDATAFORMAT_WAVEFORMATEX);

    return STATUS_SUCCESS;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -