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

📄 pa_win_wmme.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;        outputStreamInfo = outputParameters->hostApiSpecificStreamInfo;        /* all standard sample formats are supported by the buffer adapter,            this implementation doesn't support any custom sample formats */        if( outputSampleFormat & paCustomFormat )            return paSampleFormatNotSupported;        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification                && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )        {            outputMultipleDeviceChannelCount = 0;            for( i=0; i< outputStreamInfo->deviceCount; ++i )            {                outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount;                                    outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ];                /* check that output device can support outputChannelCount */                if( outputStreamInfo->devices[i].channelCount <= 0                        || outputStreamInfo->devices[i].channelCount > outputDeviceInfo->maxOutputChannels )                    return paInvalidChannelCount;                /* test for valid sample rate, see comment above */                winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device );                paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate );                if( paerror != paNoError )                    return paInvalidSampleRate;            }                            if( outputMultipleDeviceChannelCount != outputChannelCount )                return paIncompatibleHostApiSpecificStreamInfo;                    }        else        {            if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )                return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */            outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ];            /* check that output device can support outputChannelCount */            if( outputChannelCount > outputDeviceInfo->maxOutputChannels )                return paInvalidChannelCount;            /* test for valid sample rate, see comment above */            winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device );            paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate );            if( paerror != paNoError )                return paInvalidSampleRate;        }    }        /*            - if a full duplex stream is requested, check that the combination                of input and output parameters is supported            - check that the device supports sampleRate            for mme all we can do is test that the input and output devices            support the requested sample rate and number of channels. we            cannot test for full duplex compatibility.    */                                                 return paFormatIsSupported;}static void SelectBufferSizeAndCount( unsigned long baseBufferSize,    unsigned long requestedLatency,    unsigned long baseBufferCount, unsigned long minimumBufferCount,    unsigned long maximumBufferSize, unsigned long *hostBufferSize,    unsigned long *hostBufferCount ){    unsigned long sizeMultiplier, bufferCount, latency;    unsigned long nextLatency, nextBufferSize;    int baseBufferSizeIsPowerOfTwo;        sizeMultiplier = 1;    bufferCount = baseBufferCount;    /* count-1 below because latency is always determined by one less        than the total number of buffers.    */    latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);    if( latency > requestedLatency )    {        /* reduce number of buffers without falling below suggested latency */        nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )        {            --bufferCount;            nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);        }    }else if( latency < requestedLatency ){        baseBufferSizeIsPowerOfTwo = (! (baseBufferSize & (baseBufferSize - 1)));        if( baseBufferSizeIsPowerOfTwo ){            /* double size of buffers without exceeding requestedLatency */            nextBufferSize = (baseBufferSize * (sizeMultiplier*2));            nextLatency = nextBufferSize * (bufferCount-1);            while( nextBufferSize <= maximumBufferSize                    && nextLatency < requestedLatency )            {                sizeMultiplier *= 2;                nextBufferSize = (baseBufferSize * (sizeMultiplier*2));                nextLatency = nextBufferSize * (bufferCount-1);            }           }else{            /* increase size of buffers upto first excess of requestedLatency */            nextBufferSize = (baseBufferSize * (sizeMultiplier+1));            nextLatency = nextBufferSize * (bufferCount-1);            while( nextBufferSize <= maximumBufferSize                    && nextLatency < requestedLatency )            {                ++sizeMultiplier;                nextBufferSize = (baseBufferSize * (sizeMultiplier+1));                nextLatency = nextBufferSize * (bufferCount-1);            }            if( nextLatency < requestedLatency )                ++sizeMultiplier;                    }        /* increase number of buffers until requestedLatency is reached */        latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);        while( latency < requestedLatency )        {            ++bufferCount;            latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);        }    }    *hostBufferSize = baseBufferSize * sizeMultiplier;    *hostBufferCount = bufferCount;}static void ReselectBufferCount( unsigned long bufferSize,    unsigned long requestedLatency,    unsigned long baseBufferCount, unsigned long minimumBufferCount,    unsigned long *hostBufferCount ){    unsigned long bufferCount, latency;    unsigned long nextLatency;    bufferCount = baseBufferCount;    /* count-1 below because latency is always determined by one less        than the total number of buffers.    */    latency = bufferSize * (bufferCount-1);    if( latency > requestedLatency )    {        /* reduce number of buffers without falling below suggested latency */        nextLatency = bufferSize * (bufferCount-2);        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )        {            --bufferCount;            nextLatency = bufferSize * (bufferCount-2);        }    }else if( latency < requestedLatency ){        /* increase number of buffers until requestedLatency is reached */        latency = bufferSize * (bufferCount-1);        while( latency < requestedLatency )        {            ++bufferCount;            latency = bufferSize * (bufferCount-1);        }                                                             }    *hostBufferCount = bufferCount;}/* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount,   framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values   of the other parameters.*/static PaError CalculateBufferSettings(        unsigned long *framesPerHostInputBuffer, unsigned long *hostInputBufferCount,        unsigned long *framesPerHostOutputBuffer, unsigned long *hostOutputBufferCount,        int inputChannelCount, PaSampleFormat hostInputSampleFormat,        PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo,        int outputChannelCount, PaSampleFormat hostOutputSampleFormat,        PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo,        double sampleRate, unsigned long framesPerBuffer ){    PaError result = paNoError;    int effectiveInputChannelCount, effectiveOutputChannelCount;    int hostInputFrameSize = 0;    unsigned int i;        if( inputChannelCount > 0 )    {        int hostInputSampleSize = Pa_GetSampleSize( hostInputSampleFormat );        if( hostInputSampleSize < 0 )        {            result = hostInputSampleSize;            goto error;        }        if( inputStreamInfo                && ( inputStreamInfo->flags & paWinMmeUseMultipleDevices ) )        {            /* set effectiveInputChannelCount to the largest number of                channels on any one device.            */            effectiveInputChannelCount = 0;            for( i=0; i< inputStreamInfo->deviceCount; ++i )            {                if( inputStreamInfo->devices[i].channelCount > effectiveInputChannelCount )                    effectiveInputChannelCount = inputStreamInfo->devices[i].channelCount;            }        }        else        {            effectiveInputChannelCount = inputChannelCount;        }        hostInputFrameSize = hostInputSampleSize * effectiveInputChannelCount;        if( inputStreamInfo                && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )        {            if( inputStreamInfo->bufferCount <= 0                    || inputStreamInfo->framesPerBuffer <= 0 )            {                result = paIncompatibleHostApiSpecificStreamInfo;                goto error;            }            *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer;            *hostInputBufferCount = inputStreamInfo->bufferCount;        }        else        {            unsigned long hostBufferSizeBytes, hostBufferCount;            unsigned long minimumBufferCount = (outputChannelCount > 0)                    ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_                    : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_;            unsigned long maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostInputFrameSize);            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;            /* compute the following in bytes, then convert back to frames */            SelectBufferSizeAndCount(                ((framesPerBuffer == paFramesPerBufferUnspecified)                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_                    : framesPerBuffer ) * hostInputFrameSize, /* baseBufferSize */                ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */                4, /* baseBufferCount */                minimumBufferCount, maximumBufferSize,                &hostBufferSizeBytes, &hostBufferCount );            *framesPerHostInputBuffer = hostBufferSizeBytes / hostInputFrameSize;            *hostInputBufferCount = hostBufferCount;        }    }    else    {        *framesPerHostInputBuffer = 0;        *hostInputBufferCount = 0;    }    if( outputChannelCount > 0 )    {        if( outputStreamInfo                && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )        {            if( outputStreamInfo->bufferCount <= 0                    || outputStreamInfo->framesPerBuffer <= 0 )            {                result = paIncompatibleHostApiSpecificStreamInfo;                goto error;            }            *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer;            *hostOutputBufferCount = outputStreamInfo->bufferCount;                        if( inputChannelCount > 0 ) /* full duplex */            {                if( *framesPerHostInputBuffer != *framesPerHostOutputBuffer )                {                    if( inputStreamInfo                            && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )                    {                         /* a custom StreamInfo was used for specifying both input                            and output buffer sizes, the larger buffer size                            must be a multiple of the smaller buffer size */                        if( *framesPerHostInputBuffer < *framesPerHostOutputBuffer )                        {                            if( *framesPerHostOutputBuffer % *framesPerHostInputBuffer != 0 )                            {                                result = paIncompatibleHostApiSpecificStreamInfo;                                goto error;                            }                        }                        else                        {                            assert( *framesPerHostInputBuffer > *framesPerHostOutputBuffer );                            if( *framesPerHostInputBuffer % *framesPerHostOutputBuffer != 0 )                            {                                result = paIncompatibleHostApiSpecificStreamInfo;                                goto error;                            }                        }                                            }                    else                    {                        /* a custom StreamInfo was not used for specifying the input buffer size,                            so use the output buffer size, and approximately the same latency. */                        *framesPerHostInputBuffer = *framesPerHostOutputBuffer;                        *hostInputBufferCount = (((unsigned long)(suggestedInputLatency * sampleRate)) / *framesPerHostInputBuffer) + 1;                        if( *hostInputBufferCount < PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ )                            *hostInputBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;

⌨️ 快捷键说明

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