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

📄 pa_win_wdmks.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                filter->formats |= newPin->formats;            }            if(newPin->bestSampleRate > filter->bestSampleRate)            {                filter->bestSampleRate = newPin->bestSampleRate;            }        }    }    if(( filter->maxInputChannels == 0) && ( filter->maxOutputChannels == 0))    {        /* No input or output... not valid */        valid = 0;    }    if( !valid )    {        /* No valid pin was found on this filter so we destroy it */        result = paDeviceUnavailable;        goto error;    }    /* Close the filter handle for now     * It will be opened later when needed */    FilterRelease(filter);    *error = paNoError;    return filter;error:    /*    Error cleanup    */    if( filter )    {        for( pinId = 0; pinId < filter->pinCount; pinId++ )            PinFree(filter->pins[pinId]);        PaUtil_FreeMemory( filter->pins );        if( filter->handle )            CloseHandle( filter->handle );        PaUtil_FreeMemory( filter );    }    *error = result;    return NULL;}/** * Free a previously created filter */static void FilterFree(PaWinWdmFilter* filter){    int pinId;    PA_LOGL_;    if( filter )    {        for( pinId = 0; pinId < filter->pinCount; pinId++ )            PinFree(filter->pins[pinId]);        PaUtil_FreeMemory( filter->pins );        if( filter->handle )            CloseHandle( filter->handle );        PaUtil_FreeMemory( filter );    }    PA_LOGE_;}/** * Reopen the filter handle if necessary so it can be used **/static PaError FilterUse(PaWinWdmFilter* filter){    assert( filter );    PA_LOGE_;    if( filter->handle == NULL )    {        /* Open the filter */        filter->handle = CreateFile(            filter->filterName,            GENERIC_READ | GENERIC_WRITE,            0,            NULL,            OPEN_EXISTING,            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,            NULL);        if( filter->handle == NULL )        {            return paDeviceUnavailable;        }    }    filter->usageCount++;    PA_LOGL_;    return paNoError;}/** * Release the filter handle if nobody is using it **/static void FilterRelease(PaWinWdmFilter* filter){    assert( filter );    assert( filter->usageCount > 0 );    PA_LOGE_;    filter->usageCount--;    if( filter->usageCount == 0 )    {        if( filter->handle != NULL )        {            CloseHandle( filter->handle );            filter->handle = NULL;        }    }    PA_LOGL_;}/** * Create a render (playback) Pin using the supplied format **/static PaWinWdmPin* FilterCreateRenderPin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error){    PaError result;    PaWinWdmPin* pin;    assert( filter );    pin = FilterFindViableRenderPin(filter,wfex,&result);    if(!pin)    {        goto error;    }    result = PinSetFormat(pin,wfex);    if( result != paNoError )    {        goto error;    }    result = PinInstantiate(pin);    if( result != paNoError )    {        goto error;    }    *error = paNoError;    return pin;error:    *error = result;    return NULL;}/** * Find a pin that supports the given format **/static PaWinWdmPin* FilterFindViableRenderPin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error){    int pinId;    PaWinWdmPin*  pin;    PaError result = paDeviceUnavailable;    *error = paNoError;    assert( filter );    for( pinId = 0; pinId<filter->pinCount; pinId++ )    {        pin = filter->pins[pinId];        if( pin != NULL )        {            if(( pin->dataFlow == KSPIN_DATAFLOW_IN ) &&                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))            {                result = PinIsFormatSupported( pin, wfex );                if( result == paNoError )                {                    return pin;                }            }        }    }    *error = result;    return NULL;}/** * Check if there is a pin that should playback * with the supplied format **/static PaError FilterCanCreateRenderPin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex){    PaWinWdmPin* pin;    PaError result;    assert ( filter );    pin = FilterFindViableRenderPin(filter,wfex,&result);    /* result will be paNoError if pin found     * or else an error code indicating what is wrong with the format     **/    return result;}/** * Create a capture (record) Pin using the supplied format **/static PaWinWdmPin* FilterCreateCapturePin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error){    PaError result;    PaWinWdmPin* pin;    assert( filter );    pin = FilterFindViableCapturePin(filter,wfex,&result);    if(!pin)    {        goto error;    }    result = PinSetFormat(pin,wfex);    if( result != paNoError )    {        goto error;    }    result = PinInstantiate(pin);    if( result != paNoError )    {        goto error;    }    *error = paNoError;    return pin;error:    *error = result;    return NULL;}/** * Find a capture pin that supports the given format **/static PaWinWdmPin* FilterFindViableCapturePin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex,    PaError* error){    int pinId;    PaWinWdmPin*  pin;    PaError result = paDeviceUnavailable;    *error = paNoError;    assert( filter );    for( pinId = 0; pinId<filter->pinCount; pinId++ )    {        pin = filter->pins[pinId];        if( pin != NULL )        {            if(( pin->dataFlow == KSPIN_DATAFLOW_OUT ) &&                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))            {                result = PinIsFormatSupported( pin, wfex );                if( result == paNoError )                {                    return pin;                }            }        }    }    *error = result;    return NULL;}/** * Check if there is a pin that should playback * with the supplied format **/static PaError FilterCanCreateCapturePin(PaWinWdmFilter* filter,    const WAVEFORMATEX* wfex){    PaWinWdmPin* pin;    PaError result;    assert ( filter );    pin = FilterFindViableCapturePin(filter,wfex,&result);    /* result will be paNoError if pin found     * or else an error code indicating what is wrong with the format     **/    return result;}/** * Build the list of available filters */static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi){    PaError result = paNoError;    HDEVINFO handle = NULL;    int device;    int invalidDevices;    int slot;    SP_DEVICE_INTERFACE_DATA interfaceData;    SP_DEVICE_INTERFACE_DATA aliasData;    SP_DEVINFO_DATA devInfoData;    int noError;    const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR));    unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))];    SP_DEVICE_INTERFACE_DETAIL_DATA* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)interfaceDetailsArray;    TCHAR friendlyName[MAX_PATH];    HKEY hkey;    DWORD sizeFriendlyName;    DWORD type;    PaWinWdmFilter* newFilter;    GUID* category = (GUID*)&KSCATEGORY_AUDIO;    GUID* alias_render = (GUID*)&KSCATEGORY_RENDER;    GUID* alias_capture = (GUID*)&KSCATEGORY_CAPTURE;    DWORD hasAlias;    PA_LOGE_;    devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);    /* Open a handle to search for devices (filters) */    handle = SetupDiGetClassDevs(category,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    if( handle == NULL )    {        return paUnanticipatedHostError;    }    PA_DEBUG(("Setup called\n"));    /* First let's count the number of devices so we can allocate a list */    invalidDevices = 0;    for( device = 0;;device++ )    {        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);        interfaceData.Reserved = 0;        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);        aliasData.Reserved = 0;        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);        PA_DEBUG(("Enum called\n"));        if( !noError )            break; /* No more devices */        /* Check this one has the render or capture alias */        hasAlias = 0;        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);        PA_DEBUG(("noError = %d\n",noError));        if(noError)        {            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))            {                PA_DEBUG(("Device %d has render alias\n",device));                hasAlias |= 1; /* Has render alias */            }            else            {                PA_DEBUG(("Device %d has no render alias\n",device));            }        }        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData);        if(noError)        {            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))            {                PA_DEBUG(("Device %d has capture alias\n",device));                hasAlias |= 2; /* Has capture alias */            }            else            {                PA_DEBUG(("Device %d has no capture alias\n",device));            }        }        if(!hasAlias)            invalidDevices++; /* This was not a valid capture or render audio device */    }    /* Remember how many there are */    wdmHostApi->filterCount = device-invalidDevices;    PA_DEBUG(("Interfaces found: %d\n",device-invalidDevices));    /* Now allocate the list of pointers to devices */    wdmHostApi->filters  = (PaWinWdmFilter**)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter*) * device );    if( !wdmHostApi->filters )    {        if(handle != NULL)            SetupDiDestroyDeviceInfoList(handle);        return paInsufficientMemory;    }    /* Now create filter objects for each interface found */    slot = 0;    for( device = 0;;device++ )    {        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);        interfaceData.Reserved = 0;        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);        aliasData.Reserved = 0;        devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);        devInfoData.Reserved = 0;        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);        if( !noError )            break; /* No more devices */        /* Check this one has the render or capture alias */        hasAlias = 0;        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);        if(noError)

⌨️ 快捷键说明

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