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

📄 audiopin.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
字号:
/*+++ *******************************************************************\ 
* 
*  Copyright and Disclaimer: 
*  
*     --------------------------------------------------------------- 
*     This software is provided "AS IS" without warranty of any kind, 
*     either expressed or implied, including but not limited to the 
*     implied warranties of noninfringement, merchantability and/or 
*     fitness for a particular purpose.
*     --------------------------------------------------------------- 
*   
*     Copyright (c) 2008 Conexant Systems, Inc. 
*     All rights reserved. 
*
\******************************************************************* ---*/ 

#include "AudioPin.h"
#include "Device.h"
#include "debug.h"
#include "miscfuncs.h"

const ULONG AUDIO_FRAMES_TO_CYCLE = 10;


AudioPin::AudioPin(PKSPIN    p_ks_pin,
                   NTSTATUS  &status):
BasePin(p_ks_pin)
{
    PVOID  p_context = KsPinGetDevice(p_ks_pin)->Context;
    Device* p_device   = static_cast<Device*>(p_context);

    //Fail if we have an incorrect format
    PKSDATAFORMAT_WAVEFORMATEX p_format = 
        (PKSDATAFORMAT_WAVEFORMATEX) p_ks_pin->ConnectionFormat;


    //Set the buffer size based on the current audio sampling rate

    DWORD buffer_size = 1920;
    switch(p_format->WaveFormatEx.nSamplesPerSec)
    {   
    
    case 96000:
        buffer_size = 3840;
        break;
    case 48000:
        buffer_size = 1920;
        break;
    case 44100:
        buffer_size = 1764;
        break;
    case 32000:
        buffer_size = 1280;
        break;
    default:
        status = STATUS_INVALID_PARAMETER;
        break;
    }

    // Init the base class
    if(NT_SUCCESS(status))
    {
        status = init(
            AUDIO_FRAMES_TO_CYCLE,
            buffer_size,
            100000); //frame duration
    }
}


NTSTATUS AudioPin::dispatchCreate(
                                  PKSPIN p_ks_pin,
                                  PIRP p_irp)
{
    NTSTATUS status = STATUS_SUCCESS;

    p_ks_pin->Context = new AudioPin(p_ks_pin, status);

    if(!p_ks_pin->Context)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if(!NT_SUCCESS(status))
    {
        delete (AudioPin*)p_ks_pin->Context;
    }

    return status;
}

NTSTATUS AudioPin::static_IntersectHandler(
    PKSFILTER p_filter,
    PIRP p_irp,
    PKSP_PIN p_pin_instance,
    PKSDATARANGE p_caller_data_range,      //data range to verify.
    PKSDATARANGE p_descriptor_data,        //Our data range
    ULONG buffer_size,
    PVOID p_data,
    PULONG p_data_size)
{
    if( !p_filter || !p_irp || !p_pin_instance || !p_caller_data_range || !p_descriptor_data || !p_data_size)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //Verify a match for specifier WAVEFORMATEX
    if(IsEqualGUID(p_caller_data_range->Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) &&
        (p_caller_data_range->FormatSize >= sizeof(KSDATARANGE_AUDIO)))
    {
        PKSDATARANGE_AUDIO p_user_audio_range = 
            (PKSDATARANGE_AUDIO) p_caller_data_range;
 
        PKSDATARANGE_AUDIO p_descriptor_data_range =
            (PKSDATARANGE_AUDIO) p_descriptor_data;

        //Make sure the two audio data ranges match, and return a compatible format. . .
        if((p_user_audio_range->MaximumChannels != 
            p_descriptor_data_range->MaximumChannels) ||

            (p_user_audio_range->MinimumBitsPerSample != 
            p_descriptor_data_range->MinimumBitsPerSample) ||

            (p_user_audio_range->MaximumBitsPerSample != 
            p_descriptor_data_range->MaximumBitsPerSample) ||

            (p_user_audio_range->MinimumSampleFrequency != 
            p_descriptor_data_range->MinimumSampleFrequency) ||

            (p_user_audio_range->MaximumSampleFrequency != 
            p_descriptor_data_range->MaximumSampleFrequency))
        {
            return STATUS_NO_MATCH;
        }
    }

    if (IsEqualGUID(p_caller_data_range->Specifier, KSDATAFORMAT_SPECIFIER_WILDCARD) ||
        IsEqualGUID(p_caller_data_range->Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
	{
        //If buffer_size is 0, the user just wants the size. 
        if(buffer_size == 0) 
        {
            *p_data_size = sizeof(KSDATAFORMAT_WAVEFORMATEX);
            return STATUS_BUFFER_OVERFLOW;
        }

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

        //Make sure the buffer isn't NULL.
        if(!p_data)
        {
            return STATUS_INVALID_PARAMETER;
        }

        //The buffer is big enough.  Copy in the format.
        *p_data_size = sizeof(KSDATAFORMAT_WAVEFORMATEX);

        // Copy the KSDATAFORMAT first
        RtlCopyMemory(
            p_data,
            p_descriptor_data,
            sizeof(KSDATAFORMAT));
 
        
        //Get the sampling rate
        Device* p_device = getDevice(p_irp);
        if(!p_device) 
        {
            return STATUS_UNSUCCESSFUL;
        }

        DWORD sampling_rate = 48000;

        //Now fill in the rest of the WaveFormatEx structure
        PKSDATAFORMAT_WAVEFORMATEX p_buffer = (PKSDATAFORMAT_WAVEFORMATEX) p_data;
        p_buffer->DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX);
        
        p_buffer->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
        p_buffer->WaveFormatEx.nChannels = 2;
        p_buffer->WaveFormatEx.nSamplesPerSec = sampling_rate;
        p_buffer->WaveFormatEx.nAvgBytesPerSec = ((16 * 2)/8) * sampling_rate;
        p_buffer->WaveFormatEx.nBlockAlign = (USHORT)(16 * 2)/8;
        p_buffer->WaveFormatEx.wBitsPerSample = 16;
        p_buffer->WaveFormatEx.cbSize = 0;
        
        return STATUS_SUCCESS;
    }

    return STATUS_NO_MATCH;
}


VOID AudioPin::fillFrameInfo(PKSSTREAM_HEADER  p_strm_hdr, FIELD_TYPE field_type)
{
    //We don't do frame info on the audio pin
    return;
}

PIN_TYPES AudioPin::getPinType()
{
    return PIN_TYPE_AUDIO;
}

NTSTATUS AudioPin::setState(KSSTATE to_state, KSSTATE from_state)
{
    NTSTATUS status = STATUS_SUCCESS;
    
	if(!_p_device)
	{
		return STATUS_UNSUCCESSFUL;
	}

    if(to_state == KSSTATE_ACQUIRE)
    {
        if(_p_device->acquireResources(this))
        {
            //Set the audio frequency based on the pin format
            PKSDATAFORMAT_WAVEFORMATEX p_format = 
                (PKSDATAFORMAT_WAVEFORMATEX)_p_ks_pin->ConnectionFormat;
            
            _p_device->getAudDec()->setFrequency(p_format->WaveFormatEx.nSamplesPerSec);

        }
        else
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    
    return BasePin::setState(to_state, from_state);
}

const KSPIN_DISPATCH g_audio_pin_dispatch = 
{
    AudioPin::dispatchCreate,       // Pin Create
    BasePin::dispatchClose,         // Pin Close
    BasePin::dispatchProcess,       // Pin Process
    NULL,                           // Pin Reset
    NULL,                           // Pin Set Data Format
    BasePin::dispatchSetState,      // Pin Set Device State
    NULL,                           // Pin Connect
    NULL,                           // Pin Disconnect
    NULL,                           // Clock Dispatch
    NULL                            // Allocator Dispatch
};

⌨️ 快捷键说明

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