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

📄 pa_win_wdmks.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: pa_win_wdmks.c 1097 2006-08-26 08:27:53Z rossb $ * PortAudio Windows WDM-KS interface * * Author: Andrew Baldwin * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//* * The text above constitutes the entire PortAudio license; however,  * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also  * requested that these non-binding requests be included along with the  * license above. *//** @file @ingroup hostaip_src @brief Portaudio WDM-KS host API. @note This is the implementation of the Portaudio host API using the Windows WDM/Kernel Streaming API in order to enable very low latency playback and recording on all modern Windows platforms (e.g. 2K, XP) Note: This API accesses the device drivers below the usual KMIXER component which is normally used to enable multi-client mixing and format conversion. That means that it will lock out all other users of a device for the duration of active stream using those devices*/#include <stdio.h>/* Debugging/tracing support */#define PA_LOGE_#define PA_LOGL_#ifdef __GNUC__    #include <initguid.h>    #define _WIN32_WINNT 0x0501    #define WINVER 0x0501#endif#include <string.h> /* strlen() */#include <assert.h>#include "pa_util.h"#include "pa_allocation.h"#include "pa_hostapi.h"#include "pa_stream.h"#include "pa_cpuload.h"#include "pa_process.h"#include "portaudio.h"#include <windows.h>#include <winioctl.h>#ifdef __GNUC__    #undef PA_LOGE_    #define PA_LOGE_ PA_DEBUG(("%s {\n",__FUNCTION__))    #undef PA_LOGL_    #define PA_LOGL_ PA_DEBUG(("} %s\n",__FUNCTION__))    /* These defines are set in order to allow the WIndows DirectX     * headers to compile with a GCC compiler such as MinGW     * NOTE: The headers may generate a few warning in GCC, but     * they should compile */    #define _INC_MMSYSTEM    #define _INC_MMREG    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */    #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid)    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n )    #if !defined( DEFINE_WAVEFORMATEX_GUID )        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71    #endif    #define  WAVE_FORMAT_ADPCM      0x0002    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003    #define  WAVE_FORMAT_ALAW       0x0006    #define  WAVE_FORMAT_MULAW      0x0007    #define  WAVE_FORMAT_MPEG       0x0050    #define  WAVE_FORMAT_DRM        0x0009    #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}    #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data)#endif#ifdef _MSC_VER    #define DYNAMIC_GUID(data) {data}    #define _INC_MMREG    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */    #undef DEFINE_GUID    #define DEFINE_GUID(n,data) EXTERN_C const GUID n = {data}    #define DEFINE_GUID_THUNK(n,data) DEFINE_GUID(n,data)    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK(n, STATIC_##n)    #if !defined( DEFINE_WAVEFORMATEX_GUID )        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71    #endif    #define  WAVE_FORMAT_ADPCM      0x0002    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003    #define  WAVE_FORMAT_ALAW       0x0006    #define  WAVE_FORMAT_MULAW      0x0007    #define  WAVE_FORMAT_MPEG       0x0050    #define  WAVE_FORMAT_DRM        0x0009#endif#include <ks.h>#include <ksmedia.h>#include <tchar.h>#include <assert.h>#include <stdio.h>/* These next definitions allow the use of the KSUSER DLL */typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE);extern HMODULE      DllKsUser;extern KSCREATEPIN* FunctionKsCreatePin;/* Forward definition to break circular type reference between pin and filter */struct __PaWinWdmFilter;typedef struct __PaWinWdmFilter PaWinWdmFilter;/* The Pin structure * A pin is an input or output node, e.g. for audio flow */typedef struct __PaWinWdmPin{    HANDLE                      handle;    PaWinWdmFilter*             parentFilter;    unsigned long               pinId;    KSPIN_CONNECT*              pinConnect;    unsigned long               pinConnectSize;    KSDATAFORMAT_WAVEFORMATEX*  ksDataFormatWfx;    KSPIN_COMMUNICATION         communication;    KSDATARANGE*                dataRanges;    KSMULTIPLE_ITEM*            dataRangesItem;    KSPIN_DATAFLOW              dataFlow;    KSPIN_CINSTANCES            instances;    unsigned long               frameSize;    int                         maxChannels;    unsigned long               formats;    int                         bestSampleRate;}PaWinWdmPin;/* The Filter structure * A filter has a number of pins and a "friendly name" */struct __PaWinWdmFilter{    HANDLE         handle;    int            pinCount;    PaWinWdmPin**  pins;    TCHAR          filterName[MAX_PATH];    TCHAR          friendlyName[MAX_PATH];    int            maxInputChannels;    int            maxOutputChannels;    unsigned long  formats;    int            usageCount;    int            bestSampleRate;};/* PaWinWdmHostApiRepresentation - host api datastructure specific to this implementation */typedef struct __PaWinWdmHostApiRepresentation{    PaUtilHostApiRepresentation  inheritedHostApiRep;    PaUtilStreamInterface        callbackStreamInterface;    PaUtilStreamInterface        blockingStreamInterface;    PaUtilAllocationGroup*       allocations;    PaWinWdmFilter**             filters;    int                          filterCount;}PaWinWdmHostApiRepresentation;typedef struct __PaWinWdmDeviceInfo{    PaDeviceInfo     inheritedDeviceInfo;    PaWinWdmFilter*  filter;}PaWinWdmDeviceInfo;typedef struct __DATAPACKET{    KSSTREAM_HEADER  Header;    OVERLAPPED       Signal;} DATAPACKET;/* PaWinWdmStream - a stream data structure specifically for this implementation */typedef struct __PaWinWdmStream{    PaUtilStreamRepresentation  streamRepresentation;    PaUtilCpuLoadMeasurer       cpuLoadMeasurer;    PaUtilBufferProcessor       bufferProcessor;    PaWinWdmPin*                recordingPin;    PaWinWdmPin*                playbackPin;    char*                       hostBuffer;    unsigned long               framesPerHostIBuffer;    unsigned long               framesPerHostOBuffer;    int                         bytesPerInputFrame;    int                         bytesPerOutputFrame;    int                         streamStarted;    int                         streamActive;    int                         streamStop;    int                         streamAbort;    int                         oldProcessPriority;    HANDLE                      streamThread;    HANDLE                      events[5];  /* 2 play + 2 record packets + abort events */    DATAPACKET                  packets[4]; /* 2 play + 2 record */    PaStreamFlags               streamFlags;    /* These values handle the case where the user wants to use fewer     * channels than the device has */    int                         userInputChannels;    int                         deviceInputChannels;    int                         userOutputChannels;    int                         deviceOutputChannels;    int                         inputSampleSize;    int                         outputSampleSize;}PaWinWdmStream;#include <setupapi.h>HMODULE      DllKsUser = NULL;KSCREATEPIN* FunctionKsCreatePin = NULL;/* prototypes for functions declared in this file */#ifdef __cplusplusextern "C"{#endif /* __cplusplus */PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );#ifdef __cplusplus}#endif /* __cplusplus *//* Low level I/O functions */static PaError WdmSyncIoctl(HANDLE handle,    unsigned long ioctlNumber,    void* inBuffer,    unsigned long inBufferCount,    void* outBuffer,    unsigned long outBufferCount,    unsigned long* bytesReturned);static PaError WdmGetPropertySimple(HANDLE handle,    const GUID* const guidPropertySet,    unsigned long property,    void* value,    unsigned long valueCount,    void* instance,    unsigned long instanceCount);static PaError WdmSetPropertySimple(HANDLE handle,    const GUID* const guidPropertySet,    unsigned long property,    void* value,    unsigned long valueCount,    void* instance,    unsigned long instanceCount);static PaError WdmGetPinPropertySimple(HANDLE  handle,    unsigned long pinId,    const GUID* const guidPropertySet,    unsigned long property,    void* value,    unsigned long valueCount);static PaError WdmGetPinPropertyMulti(HANDLE  handle,    unsigned long pinId,    const GUID* const guidPropertySet,    unsigned long property,    KSMULTIPLE_ITEM** ksMultipleItem);/** Pin management functions */static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error);static void PinFree(PaWinWdmPin* pin);static void PinClose(PaWinWdmPin* pin);static PaError PinInstantiate(PaWinWdmPin* pin);/*static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state); NOT USED */static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state);static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format);static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format);/* Filter management functions */static PaWinWdmFilter* FilterNew(    TCHAR* filterName,    TCHAR* friendlyName,    PaError* error);static void FilterFree(PaWinWdmFilter* filter);static PaWinWdmPin* FilterCreateRenderPin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error);static PaWinWdmPin* FilterFindViableRenderPin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error);static PaError FilterCanCreateRenderPin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex);static PaWinWdmPin* FilterCreateCapturePin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error);static PaWinWdmPin* FilterFindViableCapturePin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error);static PaError FilterCanCreateCapturePin(    PaWinWdmFilter* filter,    const WAVEFORMATEX* pwfx);static PaError FilterUse(    PaWinWdmFilter* filter);static void FilterRelease(    PaWinWdmFilter* filter);/* Interface functions */static void Terminate( struct PaUtilHostApiRepresentation *hostApi );static PaError IsFormatSupported(    struct PaUtilHostApiRepresentation *hostApi,    const PaStreamParameters *inputParameters,    const PaStreamParameters *outputParameters,    double sampleRate );static PaError OpenStream(    struct PaUtilHostApiRepresentation *hostApi,    PaStream** s,    const PaStreamParameters *inputParameters,    const PaStreamParameters *outputParameters,    double sampleRate,    unsigned long framesPerBuffer,    PaStreamFlags streamFlags,    PaStreamCallback *streamCallback,    void *userData );static PaError CloseStream( PaStream* stream );static PaError StartStream( PaStream *stream );static PaError StopStream( PaStream *stream );static PaError AbortStream( PaStream *stream );static PaError IsStreamStopped( PaStream *s );static PaError IsStreamActive( PaStream *stream );static PaTime GetStreamTime( PaStream *stream );static double GetStreamCpuLoad( PaStream* stream );static PaError ReadStream(    PaStream* stream,    void *buffer,    unsigned long frames );static PaError WriteStream(    PaStream* stream,    const void *buffer,    unsigned long frames );static signed long GetStreamReadAvailable( PaStream* stream );static signed long GetStreamWriteAvailable( PaStream* stream );/* Utility functions */static unsigned long GetWfexSize(const WAVEFORMATEX* wfex);static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi);static BOOL PinWrite(HANDLE h, DATAPACKET* p);static BOOL PinRead(HANDLE h, DATAPACKET* p);static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples);static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples);static DWORD WINAPI ProcessingThread(LPVOID pParam);/* Function bodies */static unsigned long GetWfexSize(const WAVEFORMATEX* wfex){    if( wfex->wFormatTag == WAVE_FORMAT_PCM )    {        return sizeof( WAVEFORMATEX );    }    else    {        return (sizeof( WAVEFORMATEX ) + wfex->cbSize);    }}/*Low level pin/filter access functions*/static PaError WdmSyncIoctl(    HANDLE handle,    unsigned long ioctlNumber,    void* inBuffer,    unsigned long inBufferCount,    void* outBuffer,    unsigned long outBufferCount,    unsigned long* bytesReturned){    PaError result = paNoError;    OVERLAPPED overlapped;    int boolResult;    unsigned long dummyBytesReturned;    unsigned long error;    if( !bytesReturned )    {        /* User a dummy as the caller hasn't supplied one */        bytesReturned = &dummyBytesReturned;    }    FillMemory((void *)&overlapped,sizeof(overlapped),0);    overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

⌨️ 快捷键说明

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