📄 audiopin.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 + -