📄 pa_win_wdmks.c
字号:
} if( ( pin->bestSampleRate != 48000) && (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 48000) && (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 48000) ) { pin->bestSampleRate = 48000; PA_DEBUG(("48kHz supported\n")); } else if(( pin->bestSampleRate != 48000) && ( pin->bestSampleRate != 44100 ) && (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 44100) && (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 44100) ) { pin->bestSampleRate = 44100; PA_DEBUG(("44.1kHz supported\n")); } else { pin->bestSampleRate = ((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency; } } dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); } if( result != paNoError ) goto error; /* Get instance information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CINSTANCES, &pin->instances, sizeof(KSPIN_CINSTANCES)); if( result != paNoError ) goto error; /* Success */ *error = paNoError; PA_DEBUG(("Pin created successfully\n")); PA_LOGL_; return pin;error: /* Error cleanup */ PaUtil_FreeMemory( item ); if( pin ) { PaUtil_FreeMemory( pin->pinConnect ); PaUtil_FreeMemory( pin->dataRangesItem ); PaUtil_FreeMemory( pin ); } *error = result; PA_LOGL_; return NULL;}/*Safely free all resources associated with the pin*/static void PinFree(PaWinWdmPin* pin){ PA_LOGE_; if( pin ) { PinClose(pin); if( pin->pinConnect ) { PaUtil_FreeMemory( pin->pinConnect ); } if( pin->dataRangesItem ) { PaUtil_FreeMemory( pin->dataRangesItem ); } PaUtil_FreeMemory( pin ); } PA_LOGL_;}/*If the pin handle is open, close it*/static void PinClose(PaWinWdmPin* pin){ PA_LOGE_; if( pin == NULL ) { PA_DEBUG(("Closing NULL pin!")); PA_LOGL_; return; } if( pin->handle != NULL ) { PinSetState( pin, KSSTATE_PAUSE ); PinSetState( pin, KSSTATE_STOP ); CloseHandle( pin->handle ); pin->handle = NULL; FilterRelease(pin->parentFilter); } PA_LOGL_;}/*Set the state of this (instantiated) pin*/static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state){ PaError result; PA_LOGE_; if( pin == NULL ) return paInternalError; if( pin->handle == NULL ) return paInternalError; result = WdmSetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &state, sizeof(state), NULL, 0); PA_LOGL_; return result;}static PaError PinInstantiate(PaWinWdmPin* pin){ PaError result; unsigned long createResult; KSALLOCATOR_FRAMING ksaf; KSALLOCATOR_FRAMING_EX ksafex; PA_LOGE_; if( pin == NULL ) return paInternalError; if(!pin->pinConnect) return paInternalError; FilterUse(pin->parentFilter); createResult = FunctionKsCreatePin( pin->parentFilter->handle, pin->pinConnect, GENERIC_WRITE | GENERIC_READ, &pin->handle ); PA_DEBUG(("Pin create result = %x\n",createResult)); if( createResult != ERROR_SUCCESS ) { FilterRelease(pin->parentFilter); pin->handle = NULL; return paInvalidDevice; } result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &ksaf, sizeof(ksaf), NULL, 0); if( result != paNoError ) { result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &ksafex, sizeof(ksafex), NULL, 0); if( result == paNoError ) { pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize; } } else { pin->frameSize = ksaf.FrameSize; } PA_LOGL_; return paNoError;}/* NOT USEDstatic PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state){ PaError result; if( state == NULL ) return paInternalError; if( pin == NULL ) return paInternalError; if( pin->handle == NULL ) return paInternalError; result = WdmGetPropertySimple( pin->handle, KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, state, sizeof(KSSTATE), NULL, 0); return result;}*/static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format){ unsigned long size; void* newConnect; PA_LOGE_; if( pin == NULL ) return paInternalError; if( format == NULL ) return paInternalError; size = GetWfexSize(format) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX) - sizeof(WAVEFORMATEX); if( pin->pinConnectSize != size ) { newConnect = PaUtil_AllocateMemory( size ); if( newConnect == NULL ) return paInsufficientMemory; memcpy( newConnect, (void*)pin->pinConnect, min(pin->pinConnectSize,size) ); PaUtil_FreeMemory( pin->pinConnect ); pin->pinConnect = (KSPIN_CONNECT*)newConnect; pin->pinConnectSize = size; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)((KSPIN_CONNECT*)newConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = size - sizeof(KSPIN_CONNECT); } memcpy( (void*)&(pin->ksDataFormatWfx->WaveFormatEx), format, GetWfexSize(format) ); pin->ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(format->nChannels * (format->wBitsPerSample / 8)); PA_LOGL_; return paNoError;}static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format){ KSDATARANGE_AUDIO* dataRange; unsigned long count; GUID guid = DYNAMIC_GUID( DEFINE_WAVEFORMATEX_GUID(format->wFormatTag) ); PaError result = paInvalidDevice; PA_LOGE_; if( format->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) { guid = ((WAVEFORMATEXTENSIBLE*)format)->SubFormat; } dataRange = (KSDATARANGE_AUDIO*)pin->dataRanges; for(count = 0; count<pin->dataRangesItem->Count; count++) { if(( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_AUDIO,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_WILDCARD,sizeof(GUID)) )) { /* This is an audio or wildcard datarange... */ if(( !memcmp(&(dataRange->DataRange.SubFormat),&KSDATAFORMAT_SUBTYPE_WILDCARD,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.SubFormat),&guid,sizeof(GUID)) )) { if(( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WILDCARD,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,sizeof(GUID) ))) { PA_DEBUG(("Pin:%x, DataRange:%d\n",(void*)pin,count)); PA_DEBUG(("\tFormatSize:%d, SampleSize:%d\n",dataRange->DataRange.FormatSize,dataRange->DataRange.SampleSize)); PA_DEBUG(("\tMaxChannels:%d\n",dataRange->MaximumChannels)); PA_DEBUG(("\tBits:%d-%d\n",dataRange->MinimumBitsPerSample,dataRange->MaximumBitsPerSample)); PA_DEBUG(("\tSampleRate:%d-%d\n",dataRange->MinimumSampleFrequency,dataRange->MaximumSampleFrequency)); if( dataRange->MaximumChannels < format->nChannels ) { result = paInvalidChannelCount; continue; } if( dataRange->MinimumBitsPerSample > format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if( dataRange->MaximumBitsPerSample < format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if( dataRange->MinimumSampleFrequency > format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } if( dataRange->MaximumSampleFrequency < format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } /* Success! */ PA_LOGL_; return paNoError; } } } dataRange = (KSDATARANGE_AUDIO*)( ((char*)dataRange) + dataRange->DataRange.FormatSize); } PA_LOGL_; return result;}/** * Create a new filter object */static PaWinWdmFilter* FilterNew(TCHAR* filterName, TCHAR* friendlyName, PaError* error){ PaWinWdmFilter* filter; PaError result; int pinId; int valid; /* Allocate the new filter object */ filter = (PaWinWdmFilter*)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter) ); if( !filter ) { result = paInsufficientMemory; goto error; } /* Zero the filter object - done by AllocateMemory */ /* memset( (void*)filter, 0, sizeof(PaWinWdmFilter) ); */ /* Copy the filter name */ _tcsncpy(filter->filterName, filterName, MAX_PATH); /* Copy the friendly name */ _tcsncpy(filter->friendlyName, friendlyName, MAX_PATH); /* Open the filter handle */ result = FilterUse(filter); if( result != paNoError ) { goto error; } /* Get pin count */ result = WdmGetPinPropertySimple ( filter->handle, 0, &KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &filter->pinCount, sizeof(filter->pinCount) ); if( result != paNoError) { goto error; } /* Allocate pointer array to hold the pins */ filter->pins = (PaWinWdmPin**)PaUtil_AllocateMemory( sizeof(PaWinWdmPin*) * filter->pinCount ); if( !filter->pins ) { result = paInsufficientMemory; goto error; } /* Create all the pins we can */ filter->maxInputChannels = 0; filter->maxOutputChannels = 0; filter->bestSampleRate = 0; valid = 0; for(pinId = 0; pinId < filter->pinCount; pinId++) { /* Create the pin with this Id */ PaWinWdmPin* newPin; newPin = PinNew(filter, pinId, &result); if( result == paInsufficientMemory ) goto error; if( newPin != NULL ) { filter->pins[pinId] = newPin; valid = 1; /* Get the max output channel count */ if(( newPin->dataFlow == KSPIN_DATAFLOW_IN ) && (( newPin->communication == KSPIN_COMMUNICATION_SINK) || ( newPin->communication == KSPIN_COMMUNICATION_BOTH))) { if(newPin->maxChannels > filter->maxOutputChannels) filter->maxOutputChannels = newPin->maxChannels; filter->formats |= newPin->formats; } /* Get the max input channel count */ if(( newPin->dataFlow == KSPIN_DATAFLOW_OUT ) && (( newPin->communication == KSPIN_COMMUNICATION_SINK) || ( newPin->communication == KSPIN_COMMUNICATION_BOTH))) { if(newPin->maxChannels > filter->maxInputChannels) filter->maxInputChannels = newPin->maxChannels;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -