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

📄 pa_win_wdmks.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        {            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))            {                PA_DEBUG(("Device %d has render alias\n",device));                hasAlias |= 1; /* Has render alias */            }        }        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 */            }        }        if(!hasAlias)            continue; /* This was not a valid capture or render audio device */        noError = SetupDiGetDeviceInterfaceDetail(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData);        if( noError )        {            /* Try to get the "friendly name" for this interface */            sizeFriendlyName = sizeof(friendlyName);            /* Fix contributed by Ben Allison             * Removed KEY_SET_VALUE from flags on following call             * as its causes failure when running without admin rights             * and it was not required */            hkey=SetupDiOpenDeviceInterfaceRegKey(handle,&interfaceData,0,KEY_QUERY_VALUE);            if(hkey!=INVALID_HANDLE_VALUE)            {                noError = RegQueryValueEx(hkey,TEXT("FriendlyName"),0,&type,(BYTE*)friendlyName,&sizeFriendlyName);                if( noError == ERROR_SUCCESS )                {                    PA_DEBUG(("Interface %d, Name: %s\n",device,friendlyName));                    RegCloseKey(hkey);                }                else                {                    friendlyName[0] = 0;                }            }            newFilter = FilterNew(devInterfaceDetails->DevicePath,friendlyName,&result);            if( result == paNoError )            {                PA_DEBUG(("Filter created\n"));                wdmHostApi->filters[slot] = newFilter;                slot++;            }            else            {                PA_DEBUG(("Filter NOT created\n"));                /* As there are now less filters than we initially thought                 * we must reduce the count by one */                wdmHostApi->filterCount--;            }        }    }    /* Clean up */    if(handle != NULL)        SetupDiDestroyDeviceInfoList(handle);    return paNoError;}PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){    PaError result = paNoError;    int i, deviceCount;    PaWinWdmHostApiRepresentation *wdmHostApi;    PaWinWdmDeviceInfo *deviceInfoArray;    PaWinWdmFilter* pFilter;    PaWinWdmDeviceInfo *wdmDeviceInfo;    PaDeviceInfo *deviceInfo;    PA_LOGE_;    /*    Attempt to load the KSUSER.DLL without which we cannot create pins    We will unload this on termination    */    if(DllKsUser == NULL)    {        DllKsUser = LoadLibrary(TEXT("ksuser.dll"));        if(DllKsUser == NULL)            goto error;    }    FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin");    if(FunctionKsCreatePin == NULL)        goto error;    wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) );    if( !wdmHostApi )    {        result = paInsufficientMemory;        goto error;    }    wdmHostApi->allocations = PaUtil_CreateAllocationGroup();    if( !wdmHostApi->allocations )    {        result = paInsufficientMemory;        goto error;    }    result = BuildFilterList( wdmHostApi );    if( result != paNoError )    {        goto error;    }    deviceCount = wdmHostApi->filterCount;    *hostApi = &wdmHostApi->inheritedHostApiRep;    (*hostApi)->info.structVersion = 1;    (*hostApi)->info.type = paWDMKS;    (*hostApi)->info.name = "Windows WDM-KS";    (*hostApi)->info.defaultInputDevice = paNoDevice;    (*hostApi)->info.defaultOutputDevice = paNoDevice;    if( deviceCount > 0 )    {        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(               wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo*) * deviceCount );        if( !(*hostApi)->deviceInfos )        {            result = paInsufficientMemory;            goto error;        }        /* allocate all device info structs in a contiguous block */        deviceInfoArray = (PaWinWdmDeviceInfo*)PaUtil_GroupAllocateMemory(                wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo) * deviceCount );        if( !deviceInfoArray )        {            result = paInsufficientMemory;            goto error;        }        for( i=0; i < deviceCount; ++i )        {            wdmDeviceInfo = &deviceInfoArray[i];            deviceInfo = &wdmDeviceInfo->inheritedDeviceInfo;            pFilter = wdmHostApi->filters[i];            if( pFilter == NULL )                continue;            wdmDeviceInfo->filter = pFilter;            deviceInfo->structVersion = 2;            deviceInfo->hostApi = hostApiIndex;            deviceInfo->name = (char*)pFilter->friendlyName;            PA_DEBUG(("Device found name: %s\n",(char*)pFilter->friendlyName));            deviceInfo->maxInputChannels = pFilter->maxInputChannels;            if(deviceInfo->maxInputChannels > 0)            {                /* Set the default input device to the first device we find with                 * more than zero input channels                 **/                if((*hostApi)->info.defaultInputDevice == paNoDevice)                {                    (*hostApi)->info.defaultInputDevice = i;                }            }            deviceInfo->maxOutputChannels = pFilter->maxOutputChannels;            if(deviceInfo->maxOutputChannels > 0)            {                /* Set the default output device to the first device we find with                 * more than zero output channels                 **/                if((*hostApi)->info.defaultOutputDevice == paNoDevice)                {                    (*hostApi)->info.defaultOutputDevice = i;                }            }            /* These low values are not very useful because             * a) The lowest latency we end up with can depend on many factors such             *    as the device buffer sizes/granularities, sample rate, channels and format             * b) We cannot know the device buffer sizes until we try to open/use it at             *    a particular setting             * So: we give 512x48000Hz frames as the default low input latency             **/            deviceInfo->defaultLowInputLatency = (512.0/48000.0);            deviceInfo->defaultLowOutputLatency = (512.0/48000.0);            deviceInfo->defaultHighInputLatency = (4096.0/48000.0);            deviceInfo->defaultHighOutputLatency = (4096.0/48000.0);            deviceInfo->defaultSampleRate = (double)(pFilter->bestSampleRate);            (*hostApi)->deviceInfos[i] = deviceInfo;        }    }    (*hostApi)->info.deviceCount = deviceCount;    (*hostApi)->Terminate = Terminate;    (*hostApi)->OpenStream = OpenStream;    (*hostApi)->IsFormatSupported = IsFormatSupported;    PaUtil_InitializeStreamInterface( &wdmHostApi->callbackStreamInterface, CloseStream, StartStream,                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,                                      GetStreamTime, GetStreamCpuLoad,                                      PaUtil_DummyRead, PaUtil_DummyWrite,                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );    PaUtil_InitializeStreamInterface( &wdmHostApi->blockingStreamInterface, CloseStream, StartStream,                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,                                      GetStreamTime, PaUtil_DummyGetCpuLoad,                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );    PA_LOGL_;    return result;error:    if( DllKsUser != NULL )    {        FreeLibrary( DllKsUser );        DllKsUser = NULL;    }    if( wdmHostApi )    {        PaUtil_FreeMemory( wdmHostApi->filters );        if( wdmHostApi->allocations )        {            PaUtil_FreeAllAllocations( wdmHostApi->allocations );            PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );        }        PaUtil_FreeMemory( wdmHostApi );    }    PA_LOGL_;    return result;}static void Terminate( struct PaUtilHostApiRepresentation *hostApi ){    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;    int i;    PA_LOGE_;    if( wdmHostApi->filters )    {        for( i=0; i<wdmHostApi->filterCount; i++)        {            if( wdmHostApi->filters[i] != NULL )            {                FilterFree( wdmHostApi->filters[i] );                wdmHostApi->filters[i] = NULL;            }        }    }    PaUtil_FreeMemory( wdmHostApi->filters );    if( wdmHostApi->allocations )    {        PaUtil_FreeAllAllocations( wdmHostApi->allocations );        PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );    }    PaUtil_FreeMemory( wdmHostApi );    PA_LOGL_;}static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, PaSampleFormat sampleFormat, double sampleRate, int channelCount){    PA_LOGE_;    PA_DEBUG(( "sampleFormat = %lx\n" , sampleFormat ));    PA_DEBUG(( "sampleRate = %f\n" , sampleRate ));    PA_DEBUG(( "chanelCount = %d\n", channelCount ));    pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;    pwfext->Format.nChannels = channelCount;    pwfext->Format.nSamplesPerSec = (int)sampleRate;    if(channelCount == 1)        pwfext->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT;    else        pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO;    if(sampleFormat == paFloat32)    {        pwfext->Format.nBlockAlign = channelCount * 4;        pwfext->Format.wBitsPerSample = 32;        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);        pwfext->Samples.wValidBitsPerSample = 32;        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;    }    else if(sampleFormat == paInt32)    {        pwfext->Format.nBlockAlign = channelCount * 4;        pwfext->Format.wBitsPerSample = 32;        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);        pwfext->Samples.wValidBitsPerSample = 32;        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;    }    else if(sampleFormat == paInt24)    {        pwfext->Format.nBlockAlign = channelCount * 3;        pwfext->Format.wBitsPerSample = 24;        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);        pwfext->Samples.wValidBitsPerSample = 24;        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;    }    else if(sampleFormat == paInt16)    {        pwfext->Format.nBlockAlign = channelCount * 2;        pwfext->Format.wBitsPerSample = 16;        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);        pwfext->Samples.wValidBitsPerSample = 16;        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;    }    pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign;    PA_LOGL_;}static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate ){    int inputChannelCount, outputChannelCount;    PaSampleFormat inputSampleFormat, outputSampleFormat;    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;    PaWinWdmFilter* pFilter;    int result = paFormatIsSupported;    WAVEFORMATEXTENSIBLE wfx;    PA_LOGE_;    if( inputParameters )    {        inputChannelCount = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;        /* all standard sample formats are supported by the buffer adapter,            this implementation doesn't support any custom sample formats */        if( inputSampleFormat & paCustomFormat )            return paSampleFormatNotSupported;        /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that input device can support inputChannelCount */        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )            return paInvalidChannelCount;        /* validate inputStreamInfo */        if( inputParameters->hostApiSpecificStreamInfo )            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */        /* Check that the input format is supported */        FillWFEXT(&wfx,paInt16,sampleRate,inputChannelCount);        pFilter = wdmHostApi->filters[inputParameters->device];        result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);        if( result != paNoError )        {            /* Try a WAVE_FORMAT_PCM instead */            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;            wfx.Format.cbSize = 0;            wfx.Samples.wValidBitsPerSample = 0;            wfx.dwChannelMask = 0;            wfx.SubFormat = GUID_NULL;            result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);            if( result != paNoError )                 return result;        }    }    else    {        inputChannelCount = 0;    }    if( outputParameters )    {        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;        /* all standard sample formats are supported by the buffer adapter,            this implementation doesn't support any custom sample formats */        if( outputSampleFormat & paCustomFormat )            return paSampleFormatNotSupported;        /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that output device can support outputChannelCount */        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )            return paInvalidChannelCount;        /* validate outputStreamInfo */        if( outputParameters->hostApiSpecificStreamInfo )            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */        /* Check that the output format is supported */        FillWFEXT(&wfx,paInt16,sampleRate,outputChannelCount);        pFilter = wdmHostApi->filters[outputParameters->device];        result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);        if( result != paNoError )        {            /* Try a WAVE_FORMAT_PCM instead */            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;            wfx.Format.cbSize = 0;            wfx.Samples.wValidBitsPerSample = 0;            wfx.dwChannelMask = 0;            wfx.SubFormat = GUID_NULL;            result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);            if( result != paNoError )                 return result;    

⌨️ 快捷键说明

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