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

📄 audio.cpp

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

}

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


NTSTATUS
CAudioCapturePin::
DispatchSetFormat (
    IN PKSPIN Pin,
    IN PKSDATAFORMAT OldFormat OPTIONAL,
    IN PKSMULTIPLE_ITEM OldAttributeList OPTIONAL,
    IN const KSDATARANGE *DataRange,
    IN const KSATTRIBUTE_LIST *AttributeRange OPTIONAL
    )

/*++

Routine Description:

    This is the set data format dispatch for the capture pin.  It is called
    in two circumstances.

        1: before Pin's creation dispatch has been made to verify that
           Pin -> ConnectionFormat is an acceptable format for the range
           DataRange.  In this case OldFormat is NULL.

        2: after Pin's creation dispatch has been made and an initial format
           selected in order to change the format for the pin.  In this case,
           OldFormat will not be NULL.

    Validate that the format is acceptible and perform the actions necessary
    to change format if appropriate.

Arguments:

    Pin -
        The pin this format is being set on.  The format itself will be in
        Pin -> ConnectionFormat.

    OldFormat -
        The previous format used on this pin.  If this is NULL, it is an
        indication that Pin's creation dispatch has not yet been made and
        that this is a request to validate the initial format and not to
        change formats.

    OldAttributeList -
        The old attribute list for the prior format

    DataRange -
        A range out of our list of data ranges which was determined to be
        at least a partial match for Pin -> ConnectionFormat.  If the format
        there is unacceptable for the range, STATUS_NO_MATCH should be
        returned.

    AttributeRange -
        The attribute range

Return Value:

    Success / Failure

        STATUS_SUCCESS -
            The format is acceptable / the format has been changed

        STATUS_NO_MATCH -
            The format is not-acceptable / the format has not been changed

--*/

{

    PAGED_CODE();

    //
    // This pin does not accept any format changes.  It is fixed format based
    // on what the wave file we're synthesizing from is.  Thus, we don't
    // need to worry about this being called in any context except pin
    // creation (KSPIN_FLAG_FIXED_FORMAT ensures this).  Knowing that the
    // format already is a GUID match for the range and we only have one
    // range, the interpretation without any guid checks is safe.
    //
    ASSERT (!OldFormat);

    const KSDATARANGE_AUDIO *DataRangeAudio =
        reinterpret_cast <const KSDATARANGE_AUDIO *> (DataRange);

    //
    // Verify the format is the right size.
    //
    if (Pin -> ConnectionFormat -> FormatSize <
        sizeof (KSDATAFORMAT_WAVEFORMATEX)) {

        return STATUS_NO_MATCH;
    }

    PKSDATAFORMAT_WAVEFORMATEX WaveFormat =
        reinterpret_cast <PKSDATAFORMAT_WAVEFORMATEX> (
            Pin -> ConnectionFormat
            );

    //
    // This is not an intersection, but rather a direct comparison due to
    // the fact that we're fixed to a single format and do not really have
    // a range.
    //
    if (WaveFormat -> WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM ||
        WaveFormat -> WaveFormatEx.nChannels !=
            DataRangeAudio -> MaximumChannels ||
        WaveFormat -> WaveFormatEx.nSamplesPerSec !=
            DataRangeAudio -> MaximumSampleFrequency ||
        WaveFormat -> WaveFormatEx.wBitsPerSample !=
            DataRangeAudio -> MaximumBitsPerSample) {

        return STATUS_NO_MATCH;

    }

    //
    // The format passes consideration.  Allow the pin creation with this
    // particular format.
    //
    return STATUS_SUCCESS;
    
}

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

    LOCKED CODE

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

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


NTSTATUS
CAudioCapturePin::
CaptureFrame (
    IN PKSPROCESSPIN ProcessPin,
    IN ULONG Tick
    )

/*++

Routine Description:

    Called to synthesize a frame of audio data from the wave object.

Arguments:

    ProcessPin -
        The process pin from the filter's process pins index

    Tick -
        The tick counter from the filter (the number of DPC's that have 
        happened since the DPC timer started).  Note that the DPC timer
        starts at pause and capture starts at run.

Return Value:

    Success / Failure

--*/

{

    ASSERT (ProcessPin -> Pin == m_Pin);

    //
    // Increment the frame number.  This is the total count of frames which
    // have attempted capture.
    //
    m_FrameNumber++;

    //
    // Find out how much time worth of audio data to synthesize into
    // the buffer a buffer (or how much time to skip if there are no available
    // capture buffers).
    //
    LONGLONG TimerInterval = m_ParentFilter -> GetTimerInterval ();

    //
    // Since this pin is KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING, it
    // means that we do not require frames available in order to process.
    // This means that this routine can get called from our DPC with no
    // buffers available to capture into.  In this case, we increment our
    // dropped frame counter and skip forward into the audio stream.
    //
    if (ProcessPin -> BytesAvailable) {
        //
        // Synthesize a fixed amount of audio data based on the timer interval.
        //
        ULONG BytesUsed = m_WaveObject -> SynthesizeFixed (
            TimerInterval,
            ProcessPin -> Data,
            ProcessPin -> BytesAvailable
            );
    
        ProcessPin -> BytesUsed = BytesUsed;
        ProcessPin -> Terminate = TRUE;
    
        //
        // Time stamp the packet if there is a clock assigned.
        //
        if (m_Clock) {
            PKSSTREAM_HEADER StreamHeader = 
                ProcessPin -> StreamPointer -> StreamHeader;

            StreamHeader -> PresentationTime.Time = m_Clock -> GetTime ();
            StreamHeader -> PresentationTime.Numerator =
                StreamHeader -> PresentationTime.Denominator = 1;
            StreamHeader -> OptionsFlags |=
                KSSTREAM_HEADER_OPTIONSF_TIMEVALID;
        }

    } else {
        m_DroppedFrames++;

        //
        // Since we've skipped an audio frame, inform the wave object to
        // skip forward this much.
        //
        m_WaveObject -> SkipFixed (TimerInterval);
    }
    
    return STATUS_SUCCESS;

}

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

    DESCRIPTOR / DISPATCH LAYOUT

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

//
// AudioCapturePinDispatch:
//
// This is the dispatch table for the capture pin.  It provides notifications
// about creation, closure, processing, data formats, etc...
//
const
KSPIN_DISPATCH
AudioCapturePinDispatch = {
    CAudioCapturePin::DispatchCreate,       // Pin Create
    NULL,                                   // Pin Close
    NULL,                                   // Pin Process
    NULL,                                   // Pin Reset
    CAudioCapturePin::DispatchSetFormat,    // Pin Set Data Format
    CCapturePin::DispatchSetState,          // Pin Set Device State
    NULL,                                   // Pin Connect
    NULL,                                   // Pin Disconnect
    NULL,                                   // Clock Dispatch
    NULL                                    // Allocator Dispatch
};

//
// AudioDefaultAllocatorFraming:
//
// A default framing for the audio pin.  In order for this to work properly,
// the frame size must be at least 1/fps * bytes_per_sec large.  Otherwise,
// the audio stream will fall behind.  This is dynamically adjusted when
// the actual pin is created.
//
DECLARE_SIMPLE_FRAMING_EX (
    AudioDefaultAllocatorFraming,
    STATICGUIDOF (KSMEMORY_TYPE_KERNEL_NONPAGED),
    KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
        KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY,
    25,
    0,
    2 * PAGE_SIZE,
    2 * PAGE_SIZE
    );

//
// g_PINNAME_AUDIO_CAPTURE:
//
// A GUID identifying the name of the audio capture pin.  I use the standard
// STATIC_PINNAME_VIDEO_CAPTURE for the video capture pin, but a custom name
// as defined in avssamp.inf for the audio capture pin.
//
GUID g_PINNAME_AUDIO_CAPTURE = 
    {0xba1184b9, 0x1fe6, 0x488a, 0xae, 0x78, 0x6e, 0x99, 0x7b, 0x2, 0xca, 0xea};

//
// AudioPinDescriptorTemplate:
//
// The template for the audio pin descriptor.  The audio pin on this filter
// is created dynamically -- if and only if c:\avssamp.wav exists and is
// a valid and readable wave file.
//
const
KSPIN_DESCRIPTOR_EX
AudioPinDescriptorTemplate = {
    //
    // Audio Capture Pin
    //
    &AudioCapturePinDispatch,
    NULL,
    { 
        NULL,                               // Interfaces (NULL, 0 == default)
        0,                      
        NULL,                               // Mediums (NULL, 0 == default)
        0,
        0,                                  // Range count (filled in later)
        NULL,                               // Ranges (filled in later)
        KSPIN_DATAFLOW_OUT,                 // Dataflow
        KSPIN_COMMUNICATION_BOTH,           // Communication
        &KSCATEGORY_AUDIO,                  // Category
        &g_PINNAME_AUDIO_CAPTURE,           // Name
        0                                   // Reserved
    },
    KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING | // Flags
        KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING | 
        KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY |
        KSPIN_FLAG_FIXED_FORMAT,
    1,                                      // Instances Possible
    0,                                      // Instances Necessary
    &AudioDefaultAllocatorFraming,          // Allocator Framing (filled later)
    reinterpret_cast <PFNKSINTERSECTHANDLEREX> // Intersect Handler
        (CAudioCapturePin::IntersectHandler)
};


⌨️ 快捷键说明

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