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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
            {                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_;                    }                }            }        }        else        {            unsigned long hostBufferSizeBytes, hostBufferCount;            unsigned long minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;            unsigned long maximumBufferSize;            int hostOutputFrameSize;            int hostOutputSampleSize;            hostOutputSampleSize = Pa_GetSampleSize( hostOutputSampleFormat );            if( hostOutputSampleSize < 0 )

⌨️ 快捷键说明

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